Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
定义FUNC(x,y)x=^y;y^x;在c中_C - Fatal编程技术网

定义FUNC(x,y)x=^y;y^x;在c中

定义FUNC(x,y)x=^y;y^x;在c中,c,C,当有define和两个xor表达式时,我很难理解它的含义。这个定义是什么 我尝试发送x=8,y=7,结果是x=15,y=8 为什么是幸福的 以下是节目: #define FUNC(a,b) a^=b; b ^=a; int main(){ int x=8,y= 7; FUNC(x,y); printf("%d %d\n",x, y); } 这和 int main(){ int x=8,y= 7; x^=y; y ^=x;; printf("%d

当有define和两个xor表达式时,我很难理解它的含义。这个定义是什么

我尝试发送x=8,y=7,结果是x=15,y=8 为什么是幸福的

以下是节目:

#define FUNC(a,b) a^=b; b ^=a;

int main(){
    int x=8,y= 7;
    FUNC(x,y);
    printf("%d %d\n",x, y);
}
这和

int main(){
    int x=8,y= 7;
    x^=y; y ^=x;;
    printf("%d %d\n",x, y);
}
因为定义将只是一个简单的文本替换,即所有带a的位置将替换为x,所有带b的位置将替换为y

^是位异或运算符

所以首先x=8^7=15,然后y=7^15=8

这是因为当一个位(而不是两个位)为1时,XOR产生1


定义多语句宏的规范方法是

定义FUNC do{statement1;statement2;}while0

这样即使是ifb FUNC;按打电话的人的想法做

几年前曾进行过一次讨论,导致MISRA规则发生了变化;MISRA不再推荐do策略,因为他们说应该始终使用大括号,如ifb{FUNC;},它可以优雅地处理未受保护的多语句宏,并防止像Apple证书goto这样的错误。相反,一个do{…会掩盖没有使用大括号的错误

我想我个人还是站在doside一边,如果只是因为我知道的话


还要验证技术。

更多关于原始问题:

此宏具有按位方法的前两个步骤来交换两个值:

(1) a ^= b
(2) b ^= a
(3) a ^= b
让我们稍微扩展一下:让x=a;y=b,我们将通过x和y的项来跟踪代数。首先,用其完整表达式替换每个更新:

(1) a = a ^ b
(2) b = b ^ a
(3) a = a ^ b
现在,替换x和y,从上到下滴入:

(1) a = x ^ y
(2) b = y ^ (x ^ y)
(3) a = (x ^ y) ^ (y ^ (x ^ y))
删除括号并重新排列术语:

(1) a = x ^ y
(2) b = x ^ y ^ y
(3) a = x ^ x ^ y ^ y ^ y
…留给我们的是b=x;a=y

现在,由于您只有前两个步骤,您的最终结果是

b = x (original value of a)
a = x ^ y (a.k.a. a ^ b)

这能解释您当前的问题吗?

不要这样做。使用所有警告和调试信息gcc-Wall-Wextra-g编译,然后在调试器gdb中一步一步地运行您的程序。还要查看预处理的表单gcc-Wall-C-E@BasileStarynkevitch懒得编译-代码有什么问题?易修改且容易出错;想象一个f x>0 FUNCx,y;@BasileStarynkevitch你的意思是-C?;-。而且:是的,人们应该总是使用大括号;-。@BasileStarynkevitch是的,定义是一种可怕的做法,但代码没有任何错误。它编译时没有警告。实际上,它将是x^=y;y^=x;;两个分号,这是无害的,但仍然如此。@leore是的,那怎么办?我想你是mi如果你的答案是第一个,那么你应该永远把你的宏参数括起来。@Lee或者除此之外-你不知道Shir吗?关于这种宏有很多不好的地方要说-有些是在你的答案中陈述的。但是,我认为最重要的不是你答案的一部分。那总是围绕着参数使用。所以应该是这样定义FUNCa,b do{a^=b;b^=a;}而0,因为这将发现类似于FUNCx+y,x的错误-y@StillLearning,有或没有括号,在这种特殊情况下,x+y不能是左值,否则一个简单的x++就足以说明这是不好的,但两者都会产生一个警告。@Peter,补充道,我认为它是用c编译的-我仍然没有得到任何警告。不管怎样,我的观点是在这个特殊的情况下,你会得到编译错误,不管是否有括号。但是考虑这个定义Mul10a,b a= b*10和int x=3;int y=2;Mul10y,y+x;-你会期望y=50,但是由于缺少括号,你会得到y=32。ce正确的y=50。这说明了为什么总是使用括号。
b = x (original value of a)
a = x ^ y (a.k.a. a ^ b)