【问题标题】:How do I write if conditions like these in a macro?如果在宏中出现这样的条件,我该如何编写?
【发布时间】:2016-08-24 14:16:59
【问题描述】:

我对宏很陌生。
我知道如何使用三元运算符来使用 if 条件。
如何将其转换为 #define

if(i==j)
            {
                count=count+1;
                break;
            }

我试试运气,但似乎是错的:

#define ifcount(i,j) ((i)==(j)? count=count+1\
                                    break:0)

这是我要转换的代码 http://pastebin.com/i7Tuyh00

【问题讨论】:

  • 你认为为什么需要将它转换成三进制?你可以在宏中很好地写if。只是不要忘记换行符中的反斜杠......
  • 不要滥用宏。保留代码中的中断,以便任何阅读它的人都能理解。
  • @hacks 它在第二行,如果条件不正确,我想要什么都没有发生
  • 不要更改宏内外部代码的控制流程!没有人会理解您的代码的作用。这包括几周/几个月后的你自己!
  • @EugeneSh。嗨,我看到了这个,所以我认为这将被使用stackoverflow.com/questions/12989298/…

标签: c macros c-preprocessor


【解决方案1】:

使用(滥用)宏来改变程序流程通常是个坏主意,因为阅读您的代码的人(几年后您自己)可能会对程序流程中的意外跳转感到惊讶。

也就是说,您的问题与三元运算符无关。实际上,三元运算符不能在其右侧包含中断,只能包含表达式。

但是宏是万能的,所以你可以这样做:

#define ifcount(i,j) if ((i)==(j)) { count=count+1; break; }

这个宏的主要问题是人们在使用它的时候会写一个;,如果在另一个if /else对之间使用它会很糟糕,没有大括号:

if (...)
    ifcount(a,b);
else // <--- syntax error because the previous ; breaks the if /else relation
    ...;

标准解决方案是使用do/while(0) 成语:

#define do { ifcount(i,j) if ((i)==(j)) { count=count+1; break; } } while (0)

但这不会起作用,因为break 会破坏这个内部while,而不是你想要的那个(感谢@abelenky)。

唯一允许复合语句并以; 结尾的其他 C 语句是这个:

#define ifcount(i,j) if ((i)==(j)) { count=count+1; break; } else

问题是,如果您在使用ifcount(i,j) 时忘记添加;,您将得到一个静默编译和令人惊讶的行为变化,而不是编译器错误。

【讨论】:

  • 好的,谢谢,但这是什么先生stackoverflow.com/questions/12989298/…
  • @HumayunAkhtar 您是否尝试控制程序的流程,例如使用break?或者您是否尝试分配表达式的结果?你链接的那个问题是试图分配一些东西。您的问题与此无关。
  • @Terminator:看起来你只是为了它而试图将程序转换为混淆宏,这没有任何意义。我猜这是某种奇怪的任务......
  • 注意什么abelenkytold我。啊!
  • @JonathanLeffler:哎哟!我知道悬空的else 有时会派上用场……正在恢复。
【解决方案2】:

我认为没有必要使用三元 (?:) 运算符。
所以这是您使用 if 语句的宏。

#define IfCount(i,j) if ((i)==(j)) { count++; break; }

用法:

IfCount(x,5);

好的,你们觉得这个怎么样?

#define IfCount(i,j) if ((i)==(j)) { count++; break; } do{}while(0)

最后一个独立的do-while-0 有几个目的:

  • 它是一个挂分号的地方,所以宏的用法看起来像“普通”C,并以分号结尾。
  • 因为do{}while(0) else 语法无效,所以它可以防止之后无意的 else 语句。

还有什么需要注意的吗?

【讨论】:

  • 这在上下文中失败:if (…) IfCount(x, 5); else … 因为这里的 else 是语法错误。这就是人们使用#define IfCount(i, j) do { if ((i) == (j)) { count++; break; } while (0) meme 的原因;它不会破坏if (…) IfCount(i, j); else … 的语法。
  • 你的版本也不行:break-statement 将跳出do-while(0) 循环,而不是外部的、用户编写的循环。
  • 哦——笨蛋!你是对的,当然。呸!那么,不要做宏试图做的事情。
  • 绝对 - 宏被误导了,我试图解决一个问题并没有帮助。如果 C 支持它,编号中断(break 2;shell 脚本中的break 2; 将修复它,但它不支持。
  • @Terminator:pastebin 中显示的代码根本不会从使用宏(调用一次)中受益。如果您没有受到某个导师的限制,那么提交带有宏(例如所提议的宏)的代码将导致立即失去分数和/或面子 - 除了作为教学练习之外,制作宏是没有意义的。我很想使用:#define if_condition_body(condition, body) if (condition) { body; } else,然后调用if_condition_body(i == j, count++; break),其中宏调用中的分号(和break)清楚地表明这不是常规函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多