深入理解一维数组与二维数组
Posted TangguTae
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解一维数组与二维数组相关的知识,希望对你有一定的参考价值。
一维数组与二维数组的传参
接收一维数组的形参有三种形式
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;
}
可以用指针来作为形参(常用的方法),也可以用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博客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*不匹配,所以也会出现随机值。
二维数组的深入理解
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第一行的首元素地址、数组名。
以上是关于深入理解一维数组与二维数组的主要内容,如果未能解决你的问题,请参考以下文章