我一直在努力理解如何使用指针算术访问多维数组的一些细节,并得出了一些似乎没有意义的结果:
#include <stdio.h>
int main(void) {
// your code goes here
char a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
printf("*(*(a + 1) + 2) :%d\n", *(*(a + 1) + 2));
printf("size of a:%d, size of *a:%d, size of **a:%d\n",
sizeof(a), sizeof(*a), sizeof(**a));
printf("value of a:%d, value of *a:%d, value of **a:%d\n",
a, *a, **a);
return 0;
}
打印
*(*(a + 1) + 2) :7
*(a + 1) :593886528
a + 1 :593886528
size of a:12, size of *a:4, size of **a:1
value of a:593886524, value of *a:593886524, value of **a:1
我不知道幕后发生了什么,因此打印 a 会为您提供 a 第一个元素的地址,取消引用它一次会再次给出相同的值而不是内容,但是,神奇的是,引用 a第二次获取实际指向的值。这个“知道何时实际取消引用的指向自身的指针(同时保持跟踪正确的大小)”是如何工作的?
数组,当在表达式中使用时,衰减为指向其第一个元素的指针。 这也适用于数组的数组。
数组的地址将与其第一个元素的地址相同(尽管类型不同)。 由于您有一个数组的数组,因此外部数组的地址与第一个内部数组的地址相同,即与内部数组的第一个元素的地址相同。
从类型的角度来看,当你打印
a
时,你会得到一个指向其第一个元素的指针。 由于 a
的类型是 char[3][4]
,这意味着数组的元素属于 char[4]
类型,并且指向这些元素的指针具有 char(*)[4]
类型。
当您打印
*a
时,该表达式的类型为 char[4]
,它也会衰减为指向其第一个类型为 char *
的元素的指针。
因此
a
和 *a
都表示数组,并且都衰减为指向其第一个元素的指针。
在侧节点上,打印指针时应使用
%p
格式说明符。 %d
说明符用于打印 int
,使用错误的格式说明符会触发代码中未定义的行为。