指针和后缀的问题

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 个元素;不幸的是,那超出了你的数组范围。此时的行为是未定义的。您可能会得到垃圾输出、您的代码代码崩溃,或者可能发生其他事情。