指针和后缀问题

时间:2019-01-04 14:57:18

标签: c arrays pointers array-indexing

因此,我必须找出为什么要打印出特定值的问题,并且已经解决了大多数问题,但是最后三个问题出了问题。

我很乐意提供帮助

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是怎么变成

3 个答案:

答案 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: 1n[-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个元素;不幸的是,这超出了数组的范围。此时,行为是不确定的。您可能会得到垃圾输出,代码崩溃或发生其他情况。