行业知识
【C语言】数组和指针的关系
文章目录
- 数组名的理解
- 一维数组传参的本质
- 指针数组和数组指针
- 二维数组传参的本质
- 函数指针
在我第二次学习数组与指针的关系时,我还是对指针和数组的关系不甚了解,打算写下这篇博文整理思路,因此适合对指针和数组的关系初有了解的人阅读
数组名的理解
对于数组名,我们做一个简单的回顾:
数组名是数组首元素的地址,但是有两个例外
int main(){int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("&arr[0] = %p\n", &arr[0]);printf("arr = %p\n", arr);return 0;}运行上述代码后可看到,两个地址相同:
那两个例外是什么呢???
- sizeof(数组名),数组名单独放在sizeof内部,此时数组名代表整个数组
#include int main(){int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("%zd\n", sizeof(arr));return 0;}2. &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素
的地址是有区别的)
int main(){int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("%p\n", arr);printf("%p\n", arr + 1);printf("%p\n", &arr + 1);return 0;}(&arr + 1) - (arr) = 00B5F994 - 00B5F96C = 0x28 = 40 - (十个整形)
(arr + 1) - (arr) = 00B5F970 - 00B5F96C = 0x4 = 4 - (一个整形)
可见,&数组名代表整个数组的地址
因此,除sizeof(数组名)和&数组名外,数组名是数组首元素的地址
一维数组传参的本质
由上述数组名的理解index.php/tags-653.html" >可以得到,一维数组传的参数是数组首元素的地址,那为什么不传数组过去呢,因为传递的参数是实际参数的临时拷贝,如果数组太大,那消耗的内存就会过多。
因此:⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。
void test(int arr[])//参数写成数组形式{printf("%d\n", sizeof(arr));}void test(int* arr)//参数写成指针形式{printf("%d\n", sizeof(arr));}int main(){int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };test(arr);return 0;}指针数组和数组指针
指针数组是存放指针的数组
数组指针是指向数组的指针
int main(){int arr1[3] = { 1,2,3 };int arr2[3] = { 4,5,6 };int arr3[3] = { 7,8,9 };//指针数组int* arr[3] = { arr1,arr2,arr3 };//数组指针int (*pa)[3] = &arr1;return 0;}!!!注意:[]的优先级要⾼于*号的
在上述代码中
指针数组:int* arr[3]中arr先和[3]结合,表示arr代表一个数组,这个数组存放的是int*类型的指针,分别是arr1``arr2``arr3
数组指针:int (*pa)[3]中pa先和*结合,表示pa是一个指针,再和int [3]结合,表示这个指针指向了一个存放整形类型的数组
二维数组传参的本质
在写三子棋时,传递的参数是二维数组board[ROW][COL]:
void InitBoard(char board[ROW][COL], int row, int col);
那我们根据一维数组传参(可以传递一维数组或者指针)的理解,是否也可以传递指针呢?
⾸先我们再次理解⼀下⼆维数组,⼆维数组其实可以看做是每个元素是⼀维数组的数组,也就是⼆维
数组的每个元素是⼀个⼀维数组。那么⼆维数组的⾸元素就是第⼀⾏,是个⼀维数组。
所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀
维数组的地址,也就是数组指针。
根据上⾯的例⼦,第⼀⾏的⼀维数组的类型就是型就是数组指针类型int [5] ,所以第⼀⾏的地址的类型
int (*)[5] 。
那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀⾏⼀维数组的地址,那么形参也是可以写成指针形式的。
总结:⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式。
函数指针
函数指针和数组指针类似
对于如下代码:
void test(){printf("hehe\n");}int Add(int x, int y){return x+y;}void (*pf1)() = &test;void (*pf2)() = test;int (*pf3)(int, int) = Add;&test和test等价
pf1先和*结合,表示pf1是指针,void ()表示指针指向的内容是一个函数指针,这个函数无参数,也无返回值(void)
pf3先和*结合,表示pf3是指针,int (int, int)表示指针指向的内容是一个函数指针,这个函数有两个int类型的参数,返回值为int类型
上一篇:蓝鲸监控怎么添加服务器?
下一篇:房子已在房产局备案怎么办