C 左侧后增量

C 左侧后增量,c,pointers,C,Pointers,我的印象是,后增量(或预增量)只能在相等(=)的右侧完成。但是我能够编译下面的代码。 你们能帮助我理解这个特定的代码吗,尤其是下面的代码。 资料来源: 我想你的印象是错的。你绝对可以这样做: *a++ = *b++; 事实上,strcpy通常就是这样实现的。您甚至可以在不使用=的情况下使用post或pre增量: a++; 没有理由不能在赋值运算符的左侧执行后增量。后增量运算符只返回对象在其先前状态下的临时副本,该临时对象(在本例中为指针)可以对其执行操作 现在,在以下情况下: *data8+

我的印象是,后增量(或预增量)只能在相等(=)的右侧完成。但是我能够编译下面的代码。 你们能帮助我理解这个特定的代码吗,尤其是下面的代码。 资料来源:


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

*a++ = *b++;
事实上,
strcpy
通常就是这样实现的。您甚至可以在不使用
=
的情况下使用post或pre增量:

a++;

没有理由不能在赋值运算符的左侧执行后增量。后增量运算符只返回对象在其先前状态下的临时副本,该临时对象(在本例中为指针)可以对其执行操作

现在,在以下情况下:

*data8++ = -*data8;
由于运算符顺序的原因,
data8
指针将首先后置递增,返回上一个指针值的副本。然后,先前的指针值将被取消引用,并在赋值运算符的右侧为表达式的结果赋值


编辑:正如其他人所指出的那样,您在写入该内存位置时多次读取而没有序列点,从而修改了
数据8的内容,因此这是未定义的行为。

++
应用于指针,而不是
数据8
所指向的值

*data8++=-*data8

相当于:

*data8 = -*data8;
data8++;
编辑:
阅读
C99标准6.5
附录C
后,很明显
=
不是序列点。标准仅提及
&&
|

由于,
data8
=
的两侧都进行了修改,没有顺序点和标准不要求先评估RHS还是先评估LHS,因此我确信这是未定义的行为


上面的这篇文章讨论了
=
不是序列点,在这里非常相关。

所以,我相当肯定这是未定义的行为。除了以下内容中的最后分号外,没有其他序列点:

    *data8++ = -*data8;
如果data8等于0x20,这是否等于:

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

因为无法做出此决定(因为您在读取变量两次时对其进行了编辑,没有交错的序列点),这是未定义的行为


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

while( data8 != data8End ) {
    *data8 = -*data8;
    data8++;
}
希望你在这里做的更简单。您正在获取输入数组,并查看它,因此它是一系列8位数字。然后,在适当的地方,你否定每一个。

我认为

*data8++=-*data8

相当于

*数据8=-*(数据8+1)

数据8=数据8+1


-*data8
分配给
*data8
,然后增加
data8
-有效地抵消
数据
等待处的
大小
字节,因此我同意您原来的帖子。这怎么不是未定义的行为呢?strcpy并不是这样实现的。您首先在较大数据块的位模式中查找字符串的结尾,然后在较大数据块中复制数据(通常为64位)。@sharth:但它是如何未定义的?我不是一个标准的瘾君子,但必须先评估RHS,然后再评估LHS。因此应该没有问题。@VladLazarenko:为什么必须在LHS之前评估RHS?我看不出有什么理由不能交错计算这两个变量,或者按相反的顺序计算。@sharth-我回去重新阅读了它。“在两个序列点之间,一个对象被多次修改,或者被修改并读取先前的值,而不是为了确定要存储的值(6.5)。”在这种情况下,读取值只是为了确定要存储的值,对吗?乍一看,我会说这是UD,但这篇文章让我困惑。你怎么看?我想你把“变量”弄糊涂了。指针的值和它存储在地址指针上的值是两个不同的东西。在这种情况下,没有人在读取变量两次时对其进行过编辑。“data8”在地址指针处的值在RHS上读取一次。它被写回一次。指针在LHS上更改一次。@JohnBode:正确<代码>数据8正在递增。但是,我们在这个表达式中读取了两次数据8。一次在左侧,一次在右侧。RHS的读取是在指针增量之前还是之后进行的?我认为这是未知的。@sharth:启蒙运动开始了。现在我明白了问题所在。
data8
在赋值运算符的两侧都没有修改,而是在LHS上修改了,但是它被读取了两次,没有顺序点来确定读取如何与写入顺序。@Jason你说得对<代码>=
这里的关键是不是序列点。这是如何定义的?这就像声称
x=-x
未定义一样。您正在修改
data8
的内容(即指针值本身),然后在没有序列点的两个不同位置将其读回。正如其他人所指出的,如果先评估LHS或RHS,您将得到两个不同的结果。。。因此,“未定义的行为”,因为C标准没有定义必须首先评估哪一侧。。。例如,LHS和RHS的评估可以交错进行!在您的示例中,有一个明确的求值顺序,因为LHS没有读取
x
的值,它只是在向其写入。所以只有一个读/写。我会以睡眠不足为借口。
    *(0x20) = -*(0x24);
while( data8 != data8End ) {
    *data8 = -*data8;
    data8++;
}