C/C++中的指针|深入理解一维数组与二维数组

一维数组与二维数组的传参 接收一维数组的形参有三种形式

void fuc1(int *arr){ } void fuc2(int arr[]){ } void fuc3(int arr[5]){ } int main() { int* arr1[5] = {0}; fuc1(arr1); fuc2(arr1); fuc3(arr1); return 0; }

【C/C++中的指针|深入理解一维数组与二维数组】可以用指针来作为形参(常用的方法),也可以用arr[]或者arr[数组长度]来接收数组。实际上一维数组的传参还需要给出数组长度,不然无法确定数组大小是多少。
void fuc4(int* arr[5]){ } void fuc5(int* *arr){ } int main() { int* arr2[5] = { NULL }; fuc4(arr2); fuc5(arr2); return 0; }

对于这种指针数组,int* arr[5]表示我需要接收指针数组,fuc5的形参为什么可以写成int* *arr呢?原因是 *arr表示接收的是一个指针,int*表示该数组里面存放的是地址,所以说地址的地址就用二级指针来作为形参。
对于指针数组不了解的可以参考详解指针数组、数组指针、函数指针_TangguTae的博客-CSDN博客C/C++中的指针|深入理解一维数组与二维数组
文章图片
https://blog.csdn.net/weixin_43164548/article/details/119788774?spm=1001.2014.3001.5501
二维数组的传参相比较一维数组的传参要复杂一点
常见的传参形式
void fuc1(int arr[3][9]){ } void fuc2(int arr[][9]){ } void fuc3(int (*arr)[9]){ }int main() { int arr[3][9] = { 0 }; fuc1(arr); fuc2(arr); fuc3(arr); return 0; }

解释:fuc1二维数组怎么定义的他就怎么写,相对于fuc1,fuc2省略了行,C语言是允许的,但是如果是省略了列,就是错误的写法,例如arr[3][ ]或者arr[ ][ ]。实参传递的是数组名,二维数组的数组名是第一行的地址,所以说,要接收arr就得使用数组指针,所以fuc3的形参就是数组指针。很多初学者可能会传二级指针,int** arr,这样也是错误的,fuc3成立二级指针就不成立。
一维数组的深入理解
int main() { int arr[] = { 1,2,3,4 }; printf("%d\n", sizeof(arr)); //16 printf("%d\n", sizeof(arr + 0)); //4 printf("%d\n", sizeof(*arr)); //4 printf("%d\n", sizeof(arr + 1)); //4 printf("%d\n", sizeof(arr[1])); //4 printf("%d\n", sizeof(&arr)); //4 printf("%d\n", sizeof(*&arr)); //16 printf("%d\n", sizeof(&arr + 1)); //4 printf("%d\n", sizeof(&arr[0])); //4 printf("%d\n", sizeof(&arr[0] + 1)); //4 return 0; }

以上结果都是在32位环境下运行得到
解释:arr是一维数组数组名,sizeof(arr)计算的是一维数组的总大小,arr+0表示的是首元素的地址,sizeof(arr)计算的是地址的大小;*arr表示数组的首元素;arr+1是数组中第二个元素的地址;arr[1]是数组中的第二个元素;&arr是整个数组的地址;*&arr取地址与解引用相互抵消,得到的是数组名;&arr+1跳跃了整个数组,任然是个地址;&arr[0]和arr+0一样,首元素地址;&arr[0]+1第二个元素的地址。
字符串数组
int main() { char c[] = { 'a','b', 'c', 'd', 'e', 'f' }; printf("%d\n", strlen(c)); printf("%d\n", strlen(c+0)); printf("%d\n", strlen(&c)); printf("%d\n", strlen(&c+1)); printf("%d\n", strlen(&c[0]+1)); return 0; }

以上结果都是随机值。
其中一个原因是末尾没有'\0',strlen是遇到'\0'才结束计算字符串的长度。&c作为实参会报警告,与strlen的形参const char*不匹配,所以也会出现随机值。
C语言常用字符串函数详解_TangguTae的博客-CSDN博客_c字符串函数C/C++中的指针|深入理解一维数组与二维数组
文章图片
https://blog.csdn.net/weixin_43164548/article/details/119982673?spm=1001.2014.3001.5501
二维数组的深入理解
int main() { int arr[3][4] = {0}; printf("%d\n", sizeof(arr)); //48 printf("%d\n", sizeof(arr[0][0])); //4 printf("%d\n", sizeof(arr[0])); //16 printf("%d\n", sizeof(arr[0]+1)); //4 printf("%d\n", sizeof(*(arr[0]+1))); //4 printf("%d\n", sizeof(arr+1)); //4 printf("%d\n", sizeof(*(arr+1))); //16 printf("%d\n", sizeof(&arr[0]+1)); //4 printf("%d\n", sizeof(*(&arr[0] + 1))); //16 printf("%d\n", sizeof(*arr)); //16 return 0; }

以上结果都是在32位环境下运行得到
解释:arr是二维数组的数组名,也是第一行的地址,所以sizeof(数组名)为整个数组的大小即3*4*4=48;arr[0][0]第一行的第一个元素,int类型;arr[0]是二维数组第一行的数组名,也是首元素地址,同样sizeof(数组名)为第二行的大小即16;arr[0]+1为第一行第二个元素的地址;*(arr[0]+1)为第一行第二个元素;arr+1位第二行数组的地址;*(arr+1)为第二行的数组名,也是第二行首元素地址,sizeof(数组名)为第二行的大小即16;&arr[0]+1,&arr[0]第一行的地址,+1变为第二行的地址,*(&arr[0] + 1),第二行数组名、首元素地址;*arr第一行的首元素地址、数组名。

    推荐阅读