在C中使用宏作为函数

在C中使用宏作为函数,c,macros,c-preprocessor,C,Macros,C Preprocessor,我想输入一个宏,它进行逐位计算并交换两个变量 我决定使用宏作为输入,而不是在程序中反复输入代码 #define swapVars(p,a,b) {p=a^b;a=^p;b=^p;} 当我在代码中使用宏时 int a = 10, b=19; int swap_dummy = 0; //May contain anything swapVars(swap_dummy, a, b); printf("a = %d | b = %d", a, b); 我在替换中出错了。宏定义是否错误?(顺便说一

我想输入一个宏,它进行逐位计算并交换两个变量

我决定使用宏作为输入,而不是在程序中反复输入代码

#define swapVars(p,a,b) {p=a^b;a=^p;b=^p;}
当我在代码中使用宏时

int a = 10, b=19;
int swap_dummy = 0; //May contain anything
swapVars(swap_dummy, a, b);
printf("a = %d   | b = %d", a, b);

我在替换中出错了。宏定义是否错误?(顺便说一句,应该是这样)。对于这种情况,什么是正确的宏?

=^
无效,您希望改为
^=
。虽然还不清楚为什么在正常赋值可以正常工作的情况下使用稍微明智的异或


但是,请确实查看您的问题的评论,为什么这不应该是一个宏。

这个问题很像“我如何以错误的方式解决问题?”

您的宏似乎是xor交换的不正确实现。我不会帮助您修复xor交换,而是将尝试以正确的方式帮助您解决问题:尽管xor交换是一个有趣的概念,但它没有实际用途。你确定这不是过早的优化吗

  • 与临时变量交换不同,它不是惯用的。首先,如果您编写了一个临时变量交换,就不会有这个问题。此外,如果你需要花时间向同事解释你的代码,那么你可能会考虑对工作场所进行更重要的优化。
  • 在这种情况下,它的定义不如典型的掉期。对
    int
    值使用异或可能导致陷阱表示,如负零。使用陷阱表示是未定义的行为。未定义的行为会导致程序以非常奇怪的方式出现故障

  • 编译器在编译更常见、定义更明确的代码方面做得更好。让编译器为您提前进行优化

  • 关于
    inline
    关键字:停止过早优化。使用简单易读的代码让您的程序正常工作,以便您可以寻求我们的帮助。一旦你有了一个工作解决方案,在必要的时候对它进行剖析,找出最重要的优化可能来自哪里。

    你应该考虑编写一个<代码>内联< /C>函数,而不是一个宏。对于宏,您失去了所有的类型安全性,这在本例中非常重要。宏不应该有
    {}
    外壳。这个版本的XOR交换失败,如果输入别名彼此,宏添加一个额外的兴奋层,如果任何一个输入有副作用:考虑<代码> SWAPVARS(TEMP,I,J++);<代码>。宏根本不是函数,它们是宏。一个问题:内联函数依赖于编译器吗?还是在标准?@ ValeCalkPoT中,正如标题标题所示,他问的是C不是C++。“内联”关键字是在C99中定义的,但更多的是提示;实现可能会忽略它。@modifiablelvalue:
    内联
    不仅仅是一个提示,它是一个ODR relaxer。@AlokSave非常好<代码>内联通常被用作北欧神话中的过早优化。尊重你的想法。但实际上我并不是为了在某个地方或某个地方使用它而这样做的。。。我只是在学C语言的宏,我学到了很多东西,对吗?我现在没有代码,我对赋值操作符的实现非常困惑(真的感觉:我的错误有那么简单吗)。关于您上次的编辑:直到今天,我才听说过内联函数(或关键字,等等)。我肯定会明白这一点,正如你所说的“停止过早地优化”。无论如何,谢谢你的建议。熟能生巧。如果你练习用模糊和不受欢迎的方式解决问题,并专注于微不足道的优化,你可能会变得非常擅长。考虑用清晰的、可移植的方式练习解决问题,并把重点放在重要的优化上。事实上,我在想我们用这种方法交换时可以节省(一点点)内存。(考虑到定义指针也使用了一些内存块这一事实)。我没有研究过这方面的问题,只是在写文章。是的,我可能错了。我不这样练习。我只是在试验。听着,我知道这是不对的。是的,从现在起,我不会练习这些事情,也不会照你说的去做D@cipher:代码也必须存在于内存中。因此,是的,您可以在堆栈上保存4个字节。但要做到这一点,您需要向函数中添加超过8字节的代码。我曾经以编写编译器为生,让我告诉你,过早优化的代码几乎总是比明确编写然后由编译器优化的代码运行得更慢、更大、更不易维护。“让你的编译器为你做过早优化”在这一点上,我不会再称优化为过早:-)