深入理解一维数组与二维数组

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*不匹配,所以也会出现随机值。

C语言常用字符串函数详解_TangguTae的博客-CSDN博客_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第一行的首元素地址、数组名。

以上是关于深入理解一维数组与二维数组的主要内容,如果未能解决你的问题,请参考以下文章

指针与一维数组和二维数组以及字符串指针数组的学习笔记

对java中hashmap深入理解

c语言中如何通过二级指针来操作二维数组

数组-二维数组

javascript与php一维数组与二维数组互转

深入理解C语言的指针