左侧后增量

时间:2012-06-18 18:20:59

标签: c pointers

我的印象是,后增量(OR preincrement)只能在相等(=)的右侧进行。但我能够编译下面的代码。 你能帮助我理解这个特定的代码,特别是在线下。 来源:http://www.ibm.com/developerworks/library/pa-dalign/

*data8++ = -*data8;


void Munge8( void *data, uint32_t size ) {
    uint8_t *data8 = (uint8_t*) data;
    uint8_t *data8End = data8 + size;

    while( data8 != data8End ) {
        *data8++ = -*data8;
    }
}

5 个答案:

答案 0 :(得分:7)

所以,我很确定这是未定义的行为。除最终分号外没有序列点:

    *data8++ = -*data8;

如果data8等于0x20,则它等于:

    *(0x20) = -*(0x20);

    *(0x20) = -*(0x24);

因为没有办法做出这个决定,(因为你在读取变量时编辑了一个变量,没有交错序列点),这是未定义的行为


我们可以谈谈下面这段代码的作用。这可能是上述代码的意图。

while( data8 != data8End ) {
    *data8 = -*data8;
    data8++;
}

你在这里做的事情希望更加直截了当。您正在接收输入数组,并查看它,因此它是一系列8位数字。然后,就地,你否定每一个。

答案 1 :(得分:3)

我猜你的印象是错误的。你绝对可以这样做:

*a++ = *b++;

事实上,这通常是strcpy的实施方式。您甚至可以在没有=的情况下进行后增量或前增量:

a++;

答案 2 :(得分:2)

++应用于指针,而不是data8指向的值。

*data8++ = -*data8;

相当于:

*data8 = -*data8;
data8++;

修改
阅读C99 standard 6.5Annex C后,很明显=不是序列点。标准仅提及&&||,?

因为data8=的两边被修改,没有序列点和标准没有强制要求首先评估RHS还是首先要评估LHS,我相信这是< em>未定义的行为。

Any good reason why assignment operator isn't a sequence point?

上面的帖子讨论=不是序列点,而且在这里非常相关。

答案 3 :(得分:1)

没有理由不能在赋值运算符的左侧进行后递增。后增量运算符只是返回其先前状态的对象的临时副本,并且该临时对象(在这种情况下是指针)可以对其执行操作。

现在,在以下情况下:

*data8++ = -*data8;

由于运算符排序,data8指针将首先后递增,返回前一指针值的副本。之前的指针值将被取消引用,并在赋值运算符的右侧分配表达式的结果。

编辑:正如其他人所指出的那样,在写入没有序列点的内存位置时,您通过多次读取来修改data8的内容,所以这是未定义的行为。

答案 4 :(得分:0)

我认为

  

* data8 ++ = - * data8;

相当于

  

* data8 = - *(data8 + 1);

     

data8 = data8 +1