a^=b^=a^=b

caofa0532 2012-11-12 03:59:07
在C语言中,上式的计算是没有定义的吗?
a^=b^=a^=b,为什么?

应该可以算吧,从右到左,a的b次方赋值给a;然后b的新a次方,赋值给b;然后新a的新b次方赋值给新a。

这样计算没有歧义把?
...全文
1578 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
mLee79 2012-11-13
  • 打赏
  • 举报
回复
未定义行为.
lin5161678 2012-11-13
  • 打赏
  • 举报
回复
引用 12 楼 baipv008 的回复:
引用 11 楼 lin5161678 的回复:引用 10 楼 rocktyt2 的回复: 赋值运算符右结合,不是未定义行为优先级和结合性 只能决定 运算符和哪些操作数结合 无法确定求值顺序 c语言 表达式求值顺序不明确的 是未定义行为 这里不是未定义行为。否则a=a+1你也要认为是未定义行为了。
a=a+1不是 a+=a+=1;就是 原因 在两个序列点中间多次读写同一个对象 int a=5 a+=1;//这里是表达式的值是6 a的值必须等到序列点才可以确定一定是6 就是说 a+=a+=1第二次读a的值的时候 不确定a有没有被加1
AndyZhang 2012-11-13
  • 打赏
  • 举报
回复
swap(a,b)就是将a,b的值交换
千树之影 2012-11-13
  • 打赏
  • 举报
回复
引用 11 楼 lin5161678 的回复:
引用 10 楼 rocktyt2 的回复: 赋值运算符右结合,不是未定义行为优先级和结合性 只能决定 运算符和哪些操作数结合 无法确定求值顺序 c语言 表达式求值顺序不明确的 是未定义行为
这里不是未定义行为。否则a=a+1你也要认为是未定义行为了。
lin5161678 2012-11-13
  • 打赏
  • 举报
回复
引用 10 楼 rocktyt2 的回复:
赋值运算符右结合,不是未定义行为
优先级和结合性 只能决定 运算符和哪些操作数结合 无法确定求值顺序 c语言 表达式求值顺序不明确的 是未定义行为
FrankHB1989 2012-11-13
  • 打赏
  • 举报
回复
明确是未定义行为。 用序列点说起来麻烦,换C11从C++11抄的sequenced before二元关系(具有传递性和反对称性,反过来就是sequenced after)来说。若求值A和B之间没有sequenced before和sequenced after关系,则称为未序列化的(unsequenced)。 首先,表达式的求值包含值的计算和副作用的产生。 其次,一个副作用若与作用在同一个标量(scalar)对象上的另一个副作用或利用同一个对象存储的值的值的计算未序列化,行为未定义。若允许存在多种子表达式之间的顺序,其中的任意顺序中存在未序列化的副作用时,行为未定义。 再次,操作数值的计算sequenced before结果的值的计算(注意不是副作用)。赋值表达式的中更新左操作数存储值(写操作)的副作用sequenced after左右操作数的值的计算,但两个操作数之间的求值未序列化,而整个赋值表达式的值是更新左操作数以后的对应的存储值。 但是,a^=b^=a^=b有了上述最后的保证仍然是不够的。多次更新a的存储值的这些副作用之间未序列化;子表达式b^=a^=b的值的计算依赖于其子表达式a^=b是否已经更新b存储值,而这个副作用和b的值的计算未序列化。无论从哪一点都可以判断出行为未定义。
rocktyt 2012-11-13
  • 打赏
  • 举报
回复
赋值运算符右结合,不是未定义行为
caofa0532 2012-11-13
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
仅供参考C/C++ code123456789101112131415161718192021222324252627282930#include <stdio.h>#define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0)char *p1="1" ,*……
能否详细解释一下,谢谢!
TrustTJM 2012-11-12
  • 打赏
  • 举报
回复
楼主,你一开始的想法就错了,^是异或的意思,把数转换成二进制再进行行异或运算
lin5161678 2012-11-12
  • 打赏
  • 举报
回复
引用 6 楼 zjs100901 的回复:
交换a和b的值,是确定的,不是未定义行为。
不是确定的 是未定义行为 在2个序列点中间多次读写同一个对象了
zjs100901 2012-11-12
  • 打赏
  • 举报
回复
交换a和b的值,是确定的,不是未定义行为。
lin5161678 2012-11-12
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
仅供参考C/C++ code123456789101112131415161718192021222324252627282930#include <stdio.h>#define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0)char *p1="1" ,*……
无法编译通过的 里面有太多错 void main就不说了 比如 ((int)p1)^=...... 强制转换得到的不能作为左值 (int)p1 不能赋值~~~~ 其他错误我就没看了
赵4老师 2012-11-12
  • 打赏
  • 举报
回复
仅供参考

#include <stdio.h>
#define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0)
char *p1="1" ,*p2="2" ;
char c1=1 , c2=2 ;
short s1=1 , s2=2 ;
int i1=1 , i2=2 ;
__int64 I1=1i64, I2=2i64;
float f1=1.0f, f2=2.0f;
double d1=1.0 , d2=2.0 ;
void main() {
SWAP((int)p1,(int)p2); printf("char * %5s, %5s\n",p1,p2);
SWAP(c1,c2); printf("char %5d, %5d\n",c1,c2);
SWAP(s1,s2); printf("short %5d, %5d\n",s1,s2);
SWAP(i1,i2); printf("int %5d, %5d\n",i1,i2);
SWAP(I1,I2); printf("__int64 %5I64d,%5I64d\n",I1,I2);
SWAP(*(int *)&f1,*(int *)&f2);printf("float %5g, %5g\n",f1,f2);
SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double %5lg, %5lg\n",d1,d2);

SWAP(c1,c1);
printf("%d\n",c1);
}
//char * 2, 1
//char 2, 1
//short 2, 1
//int 2, 1
//__int64 2, 1
//float 2, 1
//double 2, 1
//2

wizard_tiger 2012-11-12
  • 打赏
  • 举报
回复
这个结果恐怕是不确定的,应该和编译器有关。 建议楼主不要写这样的代码。
lin5161678 2012-11-12
  • 打赏
  • 举报
回复
未定义行为了 没有从右到左 c语言的求值顺序从来都是不确定的
nice_cxf 2012-11-12
  • 打赏
  • 举报
回复
这个是异或不是指数把? 是可以这样写,不过最好不要,多写几行代码不是看起来更清晰么?

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧