We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
先来看一个小例子 : 编写函数遍历一个整型数组的元素,数组最后一个元素为-1标志数组的结束。
#include <stdio.h> void test(int *a){ int x; while((x = *a++) != -1) { printf("%d\n",x); } } int main(void) { int arr[] = {1,2,3,4,5,6,-1}; test(arr); return 0; }
原理是在函数参数为数组名时,实际传递的是该数组第一个元素的地址,通过*a++即可遍历该数组。实际上*a++分三步:
*a++
下面对题目进行一下升级 : 编写函数遍历一个指针数组的元素,数组最后一个元素为NULL标志数组的结束。
#include <stdio.h> void test_char(char *s){ char *string = NULL; while((string = *s++) != NULL){ printf("%s\n",string); } } int main(void) { char *s[] = {"hello","world","ni","hao",NULL}; test_char(s); return 0; }
一运行代码,卧槽崩溃了。什么鬼。表面看起来很对啊,将数组首地址传递到函数内部,然后取出每个元素存储的字符串常量地址,再输出字符串。
盯着代码看了10分钟左右我才发现错误 : 虽然传递给函数的是数组第一个元素的地址,即0x000(为方便起见做的假设)。但是由于函数形参是char *类型,所以*s操作取得是0x000-0x001之间的数据赋值给char * string,而不是数组元素里的内容,由于这不是字符串常量的首地址,所以printf("%s\n",string);就报错了。而且还有一点是s++也不是指向数组的第二个元素。因为数组是指针数组,存放的是字符串常量的首地址,每个数组元素是8字节(32位机器4字节)。而s是char *类型,s++的结果也只是0x001。
char *
*s
printf("%s\n",string);
有什么办法让s++指向数组下一个元素,并且*s取出来的是数组元素的内容?其实将函数参数s声明为char **即可。因为编译器发现指针s存储的地址指向的是char *类型,8字节,所以*s取出来的是s存储的地址 - s存储的地址+8字节之间的内容。(后来想想第一个例子函数形参为int *a,需要一次取址取到数据。第二个例子为指针数组,需要两次取址取到数据,函数形参自然就是char **,当然这都是马后炮了)。
#include <stdio.h> void test_char(char **s){ char *string = NULL; while((string = *s++) != NULL){ printf("%s\n",string); } } int main(void) { char *s[] = {"hello","world","ni","hao",NULL}; test_char(s); return 0; }
函数形参也可以声明为char *s[],相似的还有函数形参为int a[]与int *a是等价的。
工作一年了还犯这种低级错误,真是有点羞愧啊。😂
The text was updated successfully, but these errors were encountered:
No branches or pull requests
先来看一个小例子 : 编写函数遍历一个整型数组的元素,数组最后一个元素为-1标志数组的结束。
原理是在函数参数为数组名时,实际传递的是该数组第一个元素的地址,通过
*a++
即可遍历该数组。实际上*a++
分三步:下面对题目进行一下升级 : 编写函数遍历一个指针数组的元素,数组最后一个元素为NULL标志数组的结束。
一运行代码,卧槽崩溃了。什么鬼。表面看起来很对啊,将数组首地址传递到函数内部,然后取出每个元素存储的字符串常量地址,再输出字符串。
盯着代码看了10分钟左右我才发现错误 : 虽然传递给函数的是数组第一个元素的地址,即0x000(为方便起见做的假设)。但是由于函数形参是
char *
类型,所以*s
操作取得是0x000-0x001之间的数据赋值给char * string,而不是数组元素里的内容,由于这不是字符串常量的首地址,所以printf("%s\n",string);
就报错了。而且还有一点是s++也不是指向数组的第二个元素。因为数组是指针数组,存放的是字符串常量的首地址,每个数组元素是8字节(32位机器4字节)。而s是char *类型,s++的结果也只是0x001。有什么办法让s++指向数组下一个元素,并且*s取出来的是数组元素的内容?其实将函数参数s声明为char **即可。因为编译器发现指针s存储的地址指向的是
char *
类型,8字节,所以*s
取出来的是s存储的地址 - s存储的地址+8字节之间的内容。(后来想想第一个例子函数形参为int *a,需要一次取址取到数据。第二个例子为指针数组,需要两次取址取到数据,函数形参自然就是char **,当然这都是马后炮了)。函数形参也可以声明为char *s[],相似的还有函数形参为int a[]与int *a是等价的。
工作一年了还犯这种低级错误,真是有点羞愧啊。😂
The text was updated successfully, but these errors were encountered: