小工具知识网

当前位置: 首页 > 行业知识 > 【C语言】数组和指针的关系

行业知识

【C语言】数组和指针的关系

2026-11-08 20:09:52 来源:互联网转载

文章目录

  • 数组名的理解
  • 一维数组传参的本质
  • 指针数组和数组指针
  • 二维数组传参的本质
  • 函数指针

    在我第二次学习数组与指针的关系时,我还是对指针和数组的关系不甚了解,打算写下这篇博文整理思路,因此适合对指针和数组的关系初有了解的人阅读


    数组名的理解

    对于数组名,我们做一个简单的回顾:

    数组名是数组首元素的地址,但是有两个例外

    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;}

    运行上述代码后可看到,两个地址相同:

    那两个例外是什么呢???

    1. 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类型

上一篇:蓝鲸监控怎么添加服务器?

下一篇:房子已在房产局备案怎么办