表达式中的问号运算符

16

K&R第二版(第71页)--我一定错过了解释:

sign = (s[i] == '-') ? -1 : 1;
这段内容是关于一个将字符串转换为双精度浮点数的函数。特别是在函数跳过空白字符后,它检查正负值,并将其保存为-1或+1,以便在函数末尾进行符号转换…return sign * val / power; 我希望比推断更好地理解...... 我不确定这里的: 1在做什么(或者说在任何地方都是如此)。 它似乎有点像抽象的if语句。其中检查真值,:else……是这样吗?它是否仅限于if/else
作为初学者,我之前没有遇到过这种表达式语法,所以我想知道它通常被正式的if/else替换的特定原因 - 除了可读性之外?
5个回答

21
似乎有点像一个抽象的if语句,其中?检查真假,:则是else...是这样吗?
是的,几乎是这样。它被称为“条件运算符”(有时不完全准确地称为“三元运算符”,因为它是C中唯一的三元运算符)。但它不是一个语句,而是一个表达式,它有一个值。如果第一个参数为真,则它将计算为第二个参数,否则计算为第三个参数。因此
sign = (s[i] == '-') ? -1 : 1;

等同于

if (s[i] == '-') {
    sign = -1;
} else {
    sign = 1;
}

这是条件运算符(interactive operator)的解释,讲得非常清楚。谢谢。 - d0rmLife

18

这有点像一个抽象的 if 语句。

没错。这被称为“三元条件运算符”。

普通的 if 语句适用于语句,而条件运算符适用于表达式


我想知道它经常被正规的 if/else 替代是否有特殊原因——除了一定程度上的可读性?

在某些情况下,只使用语句级别的分支可能不够,需要在表达式级别进行处理。

例如,考虑初始化:

const int foo = bar ? 5 : 3;

使用常规的 if/else 语句无法编写出此内容。


无论如何,声称它等效于 if/else 的人是不准确的。尽管生成的汇编代码通常相同,但它们并不等效,也不应被视为 if 的简写版本。简单来说,尽可能使用 if,只有在需要根据表达式进行分支时才使用条件运算符。


因为你不仅解释了"为什么",还回答了"什么",所以我选择了这个回答作为最佳答案。 - d0rmLife

3

这是三元运算符。如果s[i] == '-',则(s[i] == '-') ? -1 : 1;返回-1,否则返回1。然后将此值分配给sign。换句话说,更长的写法是:

int sign;

if(s[i] == '-')
{
  sign = -1;
}
else
{
  sign = 1;
}

“三元运算符”并不完全正确,它的正确名称应该是“条件运算符”。 - user529758

2

?: 是C语言中的条件运算符。

在您的示例中,它将产生与以下if语句相同的结果:

if (s[i] == '-')
{
    sign = -1;
}
else
{
    sign = 1;
}

0
sign = (s[i] == '-') ? -1 : 1;

是以下缩写:

if (s[i] == '-')
{
    sign = -1;
}
else
{
    sign = 1;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接