char a[5][24] = {0};
printf("%p\r\n", a);
printf("%p\r\n", a[0]);
printf("%p\r\n", *a);
printf("%p\r\n", &a[0][0]);
printf("%d\r\n", sizeof(a));
printf("%d\r\n", sizeof(a[0]));
printf("%d\r\n", sizeof(*a));
printf("%d\r\n", sizeof(&a[0][0]));
printf("%d\r\n", sizeof(a[0][0]));
output:
0x7ffd4b518aa0
0x7ffd4b518aa0
0x7ffd4b518aa0
0x7ffd4b518aa0
120
24
24
8
1
a=&a[0],a[0]=&a[0][0]
;sizeof(a)
:表示整个二维数组的大小sizeof(a[0])
:表示第一行的一维数组的大小sizeof(*a)
:*a=a[0]
,同sizeof(a[0])
sizeof(a[0][0])
:表示a[0][0]
这个元素的大小sizeof(&a[0][0])
:表示地址的大小32
位机器上占4
字节,在64
位机器上占8
字节
int a[5][5]
:二维数组char **p
:二维指针int (*p)[10]
:一个指针,指向有10
个元素的数组,也称行指针int* p[10]
:一个数组,数组内每个元素都是指针二维数组跟二级指针,没有直接关系。
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
int* *p = NULL;
p = (int**)a; /* 不做强制类型转换会报错 */
p
是二级指针,它首先是一个指针,指向一个int*
;a
是二维数组,它首先是一个指针,指向一个含有4
个元素的int
数组;a
和p
类型不相同,赋值操作需要强制类型转换。p=a[0]=&a[0][0],*p=a[0][0]=0
**p
的值报错,因为你访问了地址为0
的空间,而这个空间你是没有权限访问的- 对于一维数组:
int arr[5]={1,2,3,4,5};
int (*p1)[5] = &arr;
/*下面是错误的*/
int (*p2)[5] = arr;
&arr
是指整个数组的首地址,而arr
是指数组首元素的首地址,虽然所表示的意义不同,但二者之间的值却是相同的。
赋值符号=
号两边的数据类型必须是相同的,如果不同,则需要显示或隐式类型转换。在这里,p1
和p2
都是数组指针,指向的是整个数组。p1
这个定义的=
号两边的数据类型完全一致,而p2
这个定义的=
号两边的数据类型就不一致了(左边的类型是指向整个数组的指针,而右边的数据类型是指向单个字符的指针),因此会提示错误信息。
- 对于二维数组:
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
a[0]
是该列的首地址&a[0][0],a
是整个数组的首地址。a = a[0] = &a[0][0]
,值相同,但意义不同。