[C语言]二维数组数组名详解,及数组指针传参

[C语言]二维数组数组名详解,及数组指针传参

指针数组

存放指针的数组

int* arr[3] = { arr1, arr2, arr3 };

数组指针

指向一个数组的指针

int (*p)[5];

//int表示指向的数组的类型,p表示这个指针的名字,[5]表示这个数组有几个元素。

补充:&arr 和sizeof(arr)中的arr表示整个数组的地址

数组名arr表示什么

在一维数组中arr表示数组首元素地址

在二维数组中arr表示第1行元素的地址,arr + i表示第i行元素的地址。

*(arr + i)//一维数组中,可以依次访问到数组的每一个元素

*(*arr + i)//二维数组中,可以依次访问到第1行的每一个元素;*arr相当于首行首元素地址

*(*(arr + j) + i)//二维数组中,可以依次访问到每一行的每一个元素

补充说明:

对一个代表某元素的地址解引用,得到的是该元素

对一个代表一行元素的地址解引用,得到的是该行首元素的地址,再对这个地址解引用得到首元素

对二维数组数组名代表什么,通过代码进行演示:

int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} };

int* p1 = arr;//取出arr所代表的地址

int* p2 = arr + 1;//取出arr+1所代表的地址

int* p3 = &arr;//对arr取地址

int* p4 = &arr + 1;//对arr+1取地址

这里我们创建的arr数组为int类型的二维数组,3行5列,每列5个元素,共20字节,整个数组共15个元素,60字节

可以看到arr+1与arr相比,跳过了20字节,也就是一行,说明arr其实是首行元素的地址

而&arr+1与&arr相比,跳过了60字节,也就是整个数组,说明&arr其实是整个数组的地址

如果以一维数组的角度来看二维数组,其实3行5列的一个二维数组就相当于一个有3个元素的一维数组,只不过这个一维数组里的每个元素代表了5个元素。

所以对于二维数组传参时:

传递arr其实相当于传递了第一行的地址,它的类型是int (*arr)[5]

传递&arr其实相当于传递整个数组的地址,它的类型是int (*arr)[3][5]

代码演示一维数组及二维数组数组指针传参

一维数组传参,打印每个元素:

//形参写成"首元素地址"传参的形式

void print1(int* arr, int sz)//这里传的是arr

{

int i = 0;

for (i = 0; i < sz; i++)

{

printf("%d ", *(arr + i));

}

printf("\n");

}

//形参写成"数组指针"传参的形式

//这不是推荐的写法,仅做讲解时使用

void print2(int (*p)[10], int sz)//这里传的是&arr

{

int i = 0;

for (i = 0; i < sz; i++)

{

//*p 相当于数组名,数组名又是首元素的地址,所以*p就是&arr[0]

//这里*p相当于把数组地址变成了首元素地址

printf("%d ", *(*p + i));

}

printf("\n");

}

int main()

{

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

int sz = sizeof(arr) / sizeof(arr[0]);

print1(arr, sz);

print2(&arr, sz);

return 0;

}

二维数组传参,打印每个元素:

传递arr 则 *(p + i),p+i指向第i行,解引用得到第i行首元素的地址

*(*(p + i)+ j)可以依次访问到数组每一个元素

//形参写成"int arr[3][5]"传参的形式

void print1(int arr[3][5], int c, int r)

{

int i = 0;

for (i = 0; i < c; i++)

{

int j = 0;

for (j = 0; j < r; j++)

{

printf("%d ", arr[i][j]);

}

printf("\n");

}

}

//形参写成"数组指针"传参的形式

//这里传递的是首行元素的地址,可以理解成降维了

void print2(int(*p)[5], int c, int r)

{

int i = 0;

for (i = 0; i < c; i++)

{

int j = 0;

for (j = 0; j < r; j++)

{

//p+i是指向第i行的

//*(p+i)相当于拿到了第i行,也相当于第i行的数组名

//数组名表示首元素的地址,*(p+i) 就是第i行第一个元素的地址

printf("%d ", *(*(p + i) + j));

//printf("%d ", p[i][j]);等价于上面printf("%d ", *(*(p + i) + j));

}

printf("\n");

}

}

int main()

{

int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };

print2(arr, 3, 5);

return 0;

}

另外:

&arr和arr在传参时,虽然这两个地址的意义不同一个表示整个数组的地址,一个表示首元素地址,但单看地址都是一样的。

而在传参时,函数会为其单独开辟一块栈帧空间,这个空间里存放的仅仅是一个16进制的地址,所以要考虑接收参数时的类型,这个类型很重要,它决定了函数中这个地址表示什么意思,故需要注意类型的匹配。

相关推荐

2025年u盘低格工具排行榜前十名推荐及使用指南
手机音乐相册软件排行榜TOP10推荐
office365无法登录账号

手机音乐相册软件排行榜TOP10推荐

07-13 👁️ 8961
索泰和七彩虹哪个好
Bet体育365提款流水

索泰和七彩虹哪个好

08-23 👁️ 7867
中国导演排行榜前十名的都有谁?中国比较厉害的导演有哪些代表作