我遇到了一个有竞争力的问题,询问以下内容的输出:
#include <stdio.h>
int main()
{
int a[] = {0,1,2,3,4};
int i, *ptr;
for(ptr = a+4, i=0; i <=4; i++)
printf("%d", ptr[-i]);
return 0;
}
我确实读过这个主题:Are negative array indexes allowed in C?但是我不清楚-ve符号如何以相反的顺序生成数组,即。 4, 3, 2, 1, 0
。
答案 0 :(得分:25)
首先,回想一下,在C中,表达式ptr[index]
与*(ptr+index)
的含义相同。
现在让我们再次查看您的表达式:ptr
在循环之前设置为a+4
;然后你应用-i
索引。因此,等效指针算术表达式如下:
printf("%d", *(a+4-i));
此表达式向后迭代数组,生成您看到的结果。
答案 1 :(得分:4)
它起作用的原因是因为[]运算符执行指针添加。
参考时
a[x]
实际发生的是它获取a的内存地址并添加sizeof(int)* x
因此,如果你将ptr设置为+ 4,那么你将转到+ sizeof(int)* 4
然后,当你输入负值时,你会向后移动通过内存地址。
答案 2 :(得分:3)
a+4
给出指向a
的第五个元素的指针。因此ptr
指的是该位置。
然后循环将i
从0计算到(并包括)4。
取消引用ptr[-i]
相当于*(ptr - i)
(根据定义)。因此,由于i
为0且ptr
为a+4
,因此它等同于a+4-0
,然后是a+4-1
,然后是a+4-2
,依此类推,直到a+4-4
,这显然(等于)等于a
。
答案 3 :(得分:3)
ptr[-i]
衰变为*(ptr + (-i))
。在第一次迭代时,当i = 0
时,ptr[-i]
访问a
数组的最后一个元素,因为最初ptr被设置为等于a + 4
,这意味着 - 获取开头的地址a
并添加4 * sizeof(int)
(因为ptr
的大小为int)。在每次下一次迭代时,当i递增时,访问前一个数组元素。
答案 4 :(得分:3)
In for for statement
for(ptr = a+4, i=0; i <=4; i++)
指针ptr
设置为a+4
它也可以通过以下方式完成
ptr = &a[4];
如果托盘输出指针指向的值,例如
printf( "%d\n", *ptr );
您将获得4
。这是指针指向数组的最后一个元素。
在循环内部使用表达式ptr[-i]
。对于i等于0,它等于ptr[0]
或简单地向*ptr
,即数组的最后一个元素将被输出。
对于i等于1,表达式ptr[-i]
等同于a[4 - 1]
或简称为[3]。当等于2时表达式ptr [-i]相当于a[4 - i]
,而a[4 - 2]
又是a[2]
,依此类推。
所以你会得到
4321
答案 5 :(得分:2)
正如我在C / C ++的评论中提到的那样
a[b] == *(a+b) == b[a]
对于你的情况,所有这些都很好
printf("%d", *(a + 4 - i));
printf("%d", a[4 - i]);
printf("%d", 4[a - i]);
...