指针和后缀的问题
Issue with pointers and postfixes
所以我必须找出为什么打印出特定的值,我已经解决了大部分问题,但是,我在最后三个问题上遇到了问题。
我很乐意提供任何帮助
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是怎么来的
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 到 "left" 开始的位置,结果是 1
。
printf("mess: %d\n", n[-6]); //value: 32766
这会转到 before 数组的开始,这是未定义的行为。它可以做任何事情,但很可能它只是通过解释不应以这种方式访问的内存来打印一些垃圾值。
我不确定代码的其他语句定义得如何。这是非常糟糕的做法,请不要编写这样的代码。正如您所说的那样,它是 mess
.
首先,在执行前两个 printf()
语句后,让我们想象一下 n
指向的内存:
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]
相同,后者是值 3
。因此,该语句与
相同
printf("mess: %d\n", -(n[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)
是一样的。结果是该索引处的值。 (检查上面的可视化)。
可视化:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
^ ^ ^
// n-2 n n+2
最后,陈述3: printf("mess: %d\n", n[-6]); //value: 32766
根据指针 n
的当前内容,最不能访问的索引是 -5
,试图访问索引 -6
处的内存位置是越界访问,导致 undefined behavior。结果不能自圆其说。
可视化:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
??? ^ ^
// n-6 n-5 n
首先,请记住在 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]
- 你在 之前索引 2 个元素 n
,这给你 1。
在行
printf("mess: %d\n", n[-6]); //value: 32766
您正在尝试索引 n
之前的 6 个元素;不幸的是,那超出了你的数组范围。此时的行为是未定义的。您可能会得到垃圾输出、您的代码代码崩溃,或者可能发生其他事情。
所以我必须找出为什么打印出特定的值,我已经解决了大部分问题,但是,我在最后三个问题上遇到了问题。
我很乐意提供任何帮助
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是怎么来的
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 到 "left" 开始的位置,结果是 1
。
printf("mess: %d\n", n[-6]); //value: 32766
这会转到 before 数组的开始,这是未定义的行为。它可以做任何事情,但很可能它只是通过解释不应以这种方式访问的内存来打印一些垃圾值。
我不确定代码的其他语句定义得如何。这是非常糟糕的做法,请不要编写这样的代码。正如您所说的那样,它是 mess
.
首先,在执行前两个 printf()
语句后,让我们想象一下 n
指向的内存:
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]
相同,后者是值3
。因此,该语句与printf("mess: %d\n", -(n[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)
是一样的。结果是该索引处的值。 (检查上面的可视化)。可视化:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 }; ^ ^ ^ // n-2 n n+2
最后,陈述3:
printf("mess: %d\n", n[-6]); //value: 32766
根据指针
n
的当前内容,最不能访问的索引是-5
,试图访问索引-6
处的内存位置是越界访问,导致 undefined behavior。结果不能自圆其说。可视化:
int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 }; ??? ^ ^ // n-6 n-5 n
首先,请记住在 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]
- 你在 之前索引 2 个元素 n
,这给你 1。
在行
printf("mess: %d\n", n[-6]); //value: 32766
您正在尝试索引 n
之前的 6 个元素;不幸的是,那超出了你的数组范围。此时的行为是未定义的。您可能会得到垃圾输出、您的代码代码崩溃,或者可能发生其他事情。