int s[4][2]={1,2,3,4,5,6,7,8};
printf("\n%u,%d",s+1,*(s+1));
Ans 2665496,2665496
在二维数组中 (s+1) 给出了第二行的地址,但为什么 *(s+1) 没有给出值 3?
正如你所说的正确s+1
的是第二行的地址。所以*(s+1)
或更具可读性s[1]
的是一行,而不是一个数字。所以它不能有“价值3”。
s
有 type int [4][2]
,即它是一个数组数组。
在大多数表达式中使用,它被隐式转换为指向其第一个参数的指针,具有 type int (*)[2]
,即指向数组的指针。s+1
type int (*)[2]
,指向数组的指针也是如此。这是指向第二行的指针(不是 int,而是整行)。
*(s+1)
是指向数组的指针的取消引用。因此,它具有 type int [2]
,即整数数组。
与s
上面一样,通过在大多数上下文中使用它(一个数组)(在这种情况下作为 的参数printf
),它被隐式转换为指向其第一个元素的指针,即键入int *
一个指向 int 的指针。这是一个指向值为 3 的 int 的指针。
由于您正在打印它们假装它们是整数,并且它们都是指针,因此它们都将打印地址。地址将相同,因为数组的地址与其第一个元素的地址相同,即使传入的指针类型不同。
您有点滥用类型系统并传入与您告诉的类型不兼容的各种类型的指针printf
。这样做的原因是因为 C 可变参数没有经过类型检查。
请注意,您的数组初始化会导致 gcc 下的警告(获得版本 4.2.1):
main.c:3: warning: missing braces around initializer
main.c:3: warning: (near initialization for ‘s[0]’)
如果你想创建一个 2 行 / 4 列的数组,你必须这样做:
int s[2][4] = {{1,2,3,4}, {5,6,7,8}};
然后您可以printf
用作:
printf("%p,%d\n", s+1, **(s+1));
因为 s 实际上是一个指向指针的指针,所以如果你取消引用它,你会得到一个指针,而不是一个 int。