因此,我必须找出为什么要打印出特定值的问题,并且已经解决了大多数问题,但是最后三个问题出了问题。
我很乐意提供帮助
int main(void)
{
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
mess(&myValues[3]); //starts function mess
}
void mess(int *n)
{
printf("mess :%d\n", *n++); //prints value of 3rd index (1) and sets pointer to fourth index
printf("mess: %d\n", *++n); //sets n to 5th index and prints its value
printf("mess: %d\n", -2[n]); //value: -3
printf("mess: %d\n", (-2)[n]); //value: 1
printf("mess: %d\n", n[-6]); //value: 32766
}
我只是不明白值-3、1和32766是怎么变成
答案 0 :(得分:4)
printf("mess: %d\n", -2[n]); //value: -3
-2[n]
是-(n[2])
(有关此怪癖的说明,请参见here)。此时,n[2]
使您3
,因此-n[2]
是-3
。
printf("mess: %d\n", (-2)[n]); //value: 1
这是[-2]
,表示您开始的位置左边的2,即1
。
printf("mess: %d\n", n[-6]); //value: 32766
这转到数组开始之前的 ,这是未定义的行为。它可以做任何事情,但很可能它只是通过解释不应以这种方式访问的内存来打印一些垃圾值。
我不确定代码中其他语句的定义是否正确。这确实是不好的做法,请不要编写这样的代码。如您所言,它是mess
。
答案 1 :(得分:4)
首先,在执行前两个n
语句之后,让我们可视化printf()
指向的内存:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
^
// n
让我们一个个看
声明1: printf("mess: %d\n", -2[n]); //value: -3
Check the operator precedence。 -2[n]
被解析为-(2[n])
。因此,-
是符号,2[n]
与值n[2]
的{{1}}相同。因此,该语句与
3
可视化效果:
printf("mess: %d\n", -(n[2]) );
声明2: int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
^ ^^
// n n+2
此处,printf("mess: %d\n", (-2)[n]); //value: 1
与n[-2]
相同。结果是该索引处的值。 (检查上面的可视化)。
可视化效果:
*(n-2)
最后,声明3: int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
^ ^ ^
// n-2 n n+2
根据指针printf("mess: %d\n", n[-6]); //value: 32766
的当前内容,访问性最低的索引是n
,尝试访问索引-5
处的存储位置超出了范围,导致{ {3}}。结果无法证明。
可视化效果:
-6
答案 2 :(得分:3)
首先,请记住,在C语言中,数组索引是可交换的-a[i]
和i[a]
产生相同的结果。
所以,线
printf("mess: %d\n", -2[n]); //value: -3
相当于写作
printf( "mess: %d\n", -n[2] );
后缀[]
运算符的优先级高于一元-
运算符,因此表达式-2[n]
被解析为-(2[n])
。您正在索引n
(3)中的2个元素,并对结果求反。
在以下行中,
printf("mess: %d\n", (-2)[n]); //value: 1
表达式(-2)[n]
等效于n[-2]
-您在之前 n
索引了2个元素,从而得到1。
在线
printf("mess: %d\n", n[-6]); //value: 32766
您正在尝试在n
之前索引6个元素;不幸的是,这超出了数组的范围。此时,行为是不确定的。您可能会得到垃圾输出,代码崩溃或发生其他情况。