c语言指针和数组关系探究,小白也能看懂

in #program6 years ago

本文通过示例代码,给出我们对c语言中指针和数组之间关系的理解,希望对初学者有所帮助。

请看我们给出的精简示例代码:(测试环境:x86_64+gcc)

#include <stdio.h>int main(void) { int arr[2][3] = { {1, 2, 3}, {4, 5, 6} }; int p1 = arr[0]; int (p2)[3] = &arr[0]; int (p3)[3] = arr; int (p4)[3] = &(arr); int (p5)[3] = &arr[1]; int (p6)[2][3] = &arr; / base / printf("p0 : %p ", arr); / expect: add 4(1 * sizeof int) / printf("p1+1 : %p ", p1 + 1); / expect: add 12(3 * sizeof int) / printf("p2+1 : %p ", p2 + 1); printf("p3+1 : %p ", p3 + 1); printf("p4+1 : %p ", p4 + 1); / expect: add 24(6 * sizeof int) */ printf("p5+1 : %p ", p5 + 1); printf("p6+1 : %p ", p6 + 1); return 0;}

输出结果如下:

p0 : 0x7fff4ddbb2b0p1+1 : 0x7fff4ddbb2b4p2+1 : 0x7fff4ddbb2bcp3+1 : 0x7fff4ddbb2bcp4+1 : 0x7fff4ddbb2bcp5+1 : 0x7fff4ddbb2c8p6+1 : 0x7fff4ddbb2c8

对上面代码的理解是:

p1:类型就是int ,可以记为是一个零维指针类型,因为该指针指向的元素根本就不是一个数组
p0/p2/p3/p4/p5,类型都是int (
)[3],可以记为一维指针类型,因为该指针指向的元素是一个一维数组
p6,类型是int (*)[2][3],自然就应该记为是二维指针类型

可见,对于n-1维指针类型的指针,它的活跃范围是一个n维数组。

指针的定义很单纯,一个指针变量仅仅包含所指向数据的类型这么一个简单的属性;而数组的定义就不一样了,它承载了很多额外的属性:(以int arr[X1][X2]...[Xn]为例)

&arr+i:类型是int ()[X1]...[Xn],可以在1个arr[X1][X2]..[Xn]的n维数组之间挪动,所以&arr+1就会跳出arr的整个n维数组围
arr+i:类型是int (
)[X2]...[Xn],可以在X1个arr[X2]..[Xn]的n-1维数组之间挪动
arr[i]:类型是int (*)[X3]...[Xn],固定到上述X1个arr[X2]..[Xn]的n-1维数组中的某一个,只活跃在其内部。也就是说,在X2个arr[X3]..[Xn]的n-2维数组之间挪动
arr[i][j]:依此类推。。。

理解了这些,再回头看本文给出的代码示例,就很好理解了:

arr的类型是int ()[3],&arr的类型是int ()[2][3]
arr[0]的类型是int ,&arr[0]的类型是int ()[3]
arr[0][0]的类型是int,&arr[0][0]的类型是int *

可以认为,数组定义一套自己的东西,但是留出了一个接口开放给指针。这样,数组才得以以指针形式被访问(使用)了。。。