4

所以我必须找出为什么会打印出特定的值,并且我已经解决了大部分问题,但是最后三个有问题。

我很乐意提供任何帮助

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 是如何产生的

4

3 回答 3

4
printf("mess: %d\n", -2[n]); //value: -3

-2[n]-(n[2])(有关此怪癖的解释,请参见此处)。在这一点上,让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.

于 2019-01-04T15:03:01.070 回答
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

    检查运算符优先级-2[n]被解析为-(2[n])。因此, the-是符号,2[n]n[2]which 是值相同3。因此,该语句与

    printf("mess: %d\n", -(n[2]) );       
    

    可视化:

     int myValues[] = { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
                                           ^     ^^
                                        // n     n+2
    
  • 声明 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是访问越界,导致未定义的行为。结果无法证明。

    可视化:

     int myValues[] =      { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
                      ???    ^                  ^
           //         n-6   n-5                 n
    
于 2019-01-04T15:03:37.497 回答
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

您之前尝试索引 6 个元素n;不幸的是,这超出了您的数组范围。此时行为未定义。您可能会得到垃圾输出、代码崩溃或其他可能发生的事情。

于 2019-01-04T15:07:11.667 回答