【问题标题】:Issue with pointers and postfixes指针和后缀问题
【发布时间】:2019-01-04 14:57:17
【问题描述】:

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

我很乐意为您提供任何帮助

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

【问题讨论】:

  • 这段代码来自哪里?逃跑。
  • a[n]*(a + n) 相同。填空,你就会得到你的结果。
  • @EugeneSh。我们边做边学。没什么好害怕的。
  • @nicomp 我害怕机构会给学生提供错误的练习。

标签: c arrays pointers array-indexing


【解决方案1】:

首先,让我们可视化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] 相同,即值 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处的内存位置访问越界,导致undefined behavior。结果无法证明。

    可视化:

     int myValues[] =      { 9, 0, 12345, 1, 7, 2, 6, 3, 5, 4 };
                      ???    ^                  ^
           //         n-6   n-5                 n
    

【讨论】:

  • 非常感谢。更让人难以理解
【解决方案2】:
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

【讨论】:

  • 这不是我的代码,只是我们教授的一些代码。看看我们对这个主题的理论理解有多深......但仍然感谢您的回答有很大帮助!
【解决方案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] - 你在索引2 个元素之前 n,它给你1。

排队

printf("mess: %d\n", n[-6]); //value: 32766

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    相关资源
    最近更新 更多