【问题标题】:What's the difference between *d++ and (*d)++ in C?C中的*d++和(*d)++有什么区别?
【发布时间】:2009-10-10 18:46:09
【问题描述】:

如标题所示,有什么区别,因为这两个似乎得到了相同的结果?

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    不,它们不一样。假设d是一个指向int的指针:

    int n = 0;
    int* d = &n;
    
    *d++; // d++ then *d, but d++ is applied after the statement.
    (*d)++; // == n++, just add one to the place where d points to.
    

    我认为在 K&R 中有一个例子,我们需要将一个 c-string 复制到另一个:

    char* first = "hello world!";
    char* second = malloc(strlen(first)+1);
    ....
    
    while(*second++ = *first++)
    {
     // nothing goes here :)
    }
    

    代码很简单,将first指向的字符放入second指向的字符中,然后在表达式之后递增两个指针。当然,当最后一个字符“\0”被复制时,表达式会变成false,然后就停止了!

    【讨论】:

    • 谢谢,这正是它的作用。
    • 答案是正确的,但是来自 K&R 的例子是糟糕的风格,恕我直言。正如原始问题所示,代码的语义并非微不足道。它也可能比更传统风格的等效代码慢,因为编译器更难优化它。我的编译器课程的讲师介绍了一个使用 *foo++ 编写的复制过程,它比使用 GCC 的 foo[i++]方式
    • @Jørgen:C 语言的创建者怎么会以糟糕的风格编写 C 代码?根据定义,这就是在 C 中完成的方式。
    • 答案是正确的,但是 K&R 示例被无效执行。我想你想创建两个指针然后增加它们,而不是尝试直接增加数组。否则我认为很好的答案。
    • 还要注意sizeof(first) 已经说明了终止空值。无需添加 1。我想你在写这篇文章时已经想到了 strlen :)
    【解决方案2】:

    自增++比解引用*具有更高的运算符优先级,所以*d++自增指针d指向数组中的下一个位置,但++的结果是原始指针d,所以 *d 返回指向的原始元素。相反,(*d)++ 只是增加指向的值。

    例子:

    // Case 1
    int array[2] = {1, 2};
    int *d = &array[0];
    int x = *d++;
    assert(x == 1 && d == &array[1]);  // x gets the first element, d points to the second
    
    // Case 2
    int array[2] = {1, 2};
    int *d = &array[0];
    int x = (*d)++;
    assert(x == 1 && d == &array[0] && array[0] == 2);
    // array[0] gets incremented, d still points there, but x receives old value
    

    【讨论】:

      【解决方案3】:

      在官方 C 术语中,这些表达式确实会为您提供相同的结果,正如它们应该提供的那样。在正确的术语中,非空表达式的“结果”是该表达式的计算结果。你的两个表达式的初始值都是*d,所以结果是一样的也就不足为奇了。

      但是,C 中的每个表达式都添加到“结果”之外,有零个或多个所谓的“副作用”。而这两种表达方式的副作用是完全不同的。第一个表达式递增指针“d”的值。第二个表达式增加 '*d' 的值(指向的值)。

      【讨论】:

        【解决方案4】:

        第一个递增指针,第二个递增指向的值。

        作为一个实验,试试这个:

        int main() {
            int x = 20;
            int *d = &x;
            printf("d = %p\n", d);
            int z = (*d)++;
            printf("z = %d\n", z);
            printf("d = %p\n", d);
            int y = *d++;
            printf("y = %d\n", y);
            printf("d = %p\n", d);
        }
        

        【讨论】:

          【解决方案5】:

          它们确实返回相同的结果,但程序中的状态变化完全不同。

          如果我们只是扩展操作,这是最容易理解的。

          x = *d++;
          // same as
          x = *d;
          d += 1; // remember that pointers increment by the size of the thing they point to
          
          x = (*d)++;
          // same as
          x = *d;
          *d += 1; // unless *d is also a pointer, this will likely really just add 1
          

          【讨论】:

            【解决方案6】:

            我手边没有编译器。

            a = (*d)++;
            b = (*d);
            

            是a==b吗?我不这么认为。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-05-30
              • 1970-01-01
              • 2023-03-13
              • 2015-08-17
              • 2010-10-11
              • 2013-06-11
              相关资源
              最近更新 更多