【问题标题】:C: False condition is interpreted as true in if statementC:假条件在if语句中被解释为真
【发布时间】:2014-02-17 15:34:20
【问题描述】:

所以我有以下程序:

# define swap(a,b) temp=a; a=b; b=temp; 

int main() {
int i, j, temp;
i = 5;
j = 10;
temp = 0;
if (i > j)
    swap(i, j);
printf("%d %d %d", i, j, temp);
}

这会导致:

10, 0, 0

我不明白为什么 if (5 > 10) 条件被执行为“真”,即使 5 不大于 10。

【问题讨论】:

  • 结果 10, 0, 0 应该给您一个提示,它与评估为 true 的条件无关。

标签: c if-statement conditional-statements false-positive


【解决方案1】:

这应该教会您尽可能避免使用宏,并且总是总是在控制流语句中使用大括号。

宏展开后,你的代码会变成:

if (i > j)
    temp = i;
i = j;
j = temp;

看到问题了吗?

【讨论】:

  • 我不知道宏是如何工作的,这就是为什么它让我感到困惑,我认为它像一个函数一样被调用,但它在编译时被替换了,因为没有大括号,只有第一个语句 "temp = i" 位于 if 语句中,有道理,谢谢!
  • @EricBergman:宏的这一方面导致了一大堆陷阱。经典示例:#define add(x, y) x + y(尝试add(1, 2) * 3)和参数的多重评估。这就是为什么在生产宏中你会看到所有东西都被包裹在括号和大括号中。
  • 根据您的经验,使用宏真的有意义吗?如果你能做一个正常的功能,为什么还要使用宏?我看到你提到了“生产宏”,所以听起来它被广泛用于某些特定目的。
  • @EricBergman:在某些情况下,不使用宏会非常乏味。最值得注意的一点是宏与其参数的类型无关,而函数则不是(并且 C 没有重载来提供帮助)。我不喜欢为宏制作一个案例 for ,因为我没有在 C 语言中经过实战测试。OTOH 确实,你知道的越少,你滥用它们的次数就越多。只需将选项保留在您的脑海中,但将其放在列表的底部。
【解决方案2】:

这是因为在编译时swap(i, j);temp=a; a=b; b=temp; 替换。现在扩展的宏看起来像

 if(i > j)
    temp = i;
    i = j;
    j = temp;  

在执行时,只有temp = i 不会因为i > j 变为false 而执行。
如果您想将swap(i, j) 视为一个函数,请将您的宏定义更改为

#define swap(a,b) do {temp=a; a=b; b=temp;} while (0) 

【讨论】:

  • 有道理,这个“技巧”问题是在一次工作面试中向我提出的,但由于我不知道宏是如何工作的,所以我弄错了。我认为这就像一个普通的函数调用。谢谢。
  • @EricBergman;见编辑。现在您的代码可以正常工作了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 2012-02-24
  • 2017-12-19
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
相关资源
最近更新 更多