我需要编写表单的声明
a = a || expr;
其中应评估 expr
,并将结果分配给 a
iff a
未设置 . 这取决于逻辑OR的短路能力 .
当然,写上述内容的时间更短
a ||= expr;
但是(令我惊讶的是)C没有逻辑赋值运算符 .
所以我的问题是双重的 . 首先,是否有一种更短的方式来编写标准C中的第一个语句(三元运算符更糟糕 - a = a ? a : expr
要求我拼出 a
三次) .
其次,为什么C中没有逻辑分配?我能想到的可能原因是:
-
它使语法难以解析?
-
处理这些案件的短路有一些微妙之处吗?
-
它被认为是多余的(但这不是针对所有运营商分配的论据吗?)
EDIT
Please unlock this question because:
-
与之相关的问题(作为所谓的副本)尚未得到答复 . 该问题的(已接受)答案表明
||=
不存在,因为重复了|=
的功能 . 这是错误的答案 .|=
不会短路 . -
C和C不是相同的语言 . 我想知道为什么C没有它 . 实际上,像C这样的派生语言,特别是Java(没有像Edmund的答案中提到的遗留代码问题那样)的问题使得这个问题更加有趣 .
EDIT 2
现在看起来我原来的意图是错的 . 在 a = a || expr
语句中(其中 a
为整数且 expr
返回一个整数值,首先 a
和 expr
将隐式转换为"booleans",然后"boolean"值将分配给 a
. 这将不正确 - 积分值将丢失谢谢,Jens和Edmund .
所以对于问题的第一部分,编码我的意图的正确方法,而不是替代方法:)将是:
if (!a) a = expr;
要么
a = a ? a : expr;
他们应该优化相同(我认为)虽然我个人更喜欢第一个(因为它有一个更少 a
键入) .
但是,问题的第二部分仍然存在 . Jens和Edmund关于 a ||= expr
中含糊不清的论点同样适用于 a = a || expr
. 赋值案例可以简单地视为正常案例:
-
将
a
转换为布尔值 -
如果为true,则整个表达式的值等于
a
的布尔值 -
否则评估
expr
,将结果转换为布尔值,赋值给a
,并返回
对于赋值和正常情况,上述步骤似乎相同 .
4 回答
a ||= expr
由于其等效的a = a || expr
的短路评估而存在问题 .让
a ||= expr
函数像a = a || expr
考虑OP的断言:这不太正确 . 如果
a
评估为true
,则不会转换expr
. 如果expr
类似于scanf()
或rand()
或某些影响程序状态的函数,这会产生差异 .诸如
a ||= scanf("%d", &i) != 1;
之类的代码只会尝试在a
中使用false值扫描数据 . 尽管可以通过这种方式扩展语言,但是对于当前的||
和&&
集合的额外短路运算符可能会导致比明显简化更多的编码问题 .另一方面:一种快速的,如果模糊的方式来编写代码,其中函数在出错时返回非零代码 .
我想简单的答案是
||
是一个布尔运算符:在C中,"boolean"是0或1.操作数被隐式转换为布尔值(我没有检查过's what the spec actually says, but it'是C的行为),结果是布尔值 .改变语义以支持这种模式可能是可行的 - 直到有人依赖
||
来做它总是做的事情 .我找不到任何特殊原因,为什么运营商不存在(在C99中) .
所以我能找到的唯一原因是,C89中没有布尔类型,那些布尔运算符只能用于
if
.例:
i
现在是'1'',这对大多数人来说非常直观 .这个在没有布尔类型的情况下,运算符显然不会带来任何清晰度或编码改进,这将导致与另一个相关 .
在我看来,
a ||= b;
作为if(!a) a = b;
的实施将非常简单,并且已经通过例如Lua中 .所以你的问题似乎有点儿,为什么C的设计方式与它的设计方式相同 . 如果这个问题是关于C的话,你可以问Bjarne Stroustrup然后问他,进入他的是什么 . 由于情况并非如此,这在我看来似乎是一种死胡同,因为标准已经写了很久以前你不能再问人了,为什么h *** .
另一方面,这个不完整的算子集(在我看来)应该使用与你的相似的符号来完整,因为在我看来,没有理由反对它 .
我希望我能帮助一点 .
因为运算符
||
和&&
的返回类型与其左参数的类型不同 .||
和&&
的返回类型始终为int
1,而左参数可以是任何整数,浮点或指针类型 . 操作数也不必是同一类型 . 因此,将x ||= y
定义为x = x || y
和x &&= y
作为x = x && y
,与其他扩充分配一致,将无法将结果存储在大多数类型的参数中 .您可以提出其他定义,例如:
x ||= y
为if(!x) x = y
和x &&= y
为if(!y) x = y
,但这并不是很明显,并没有那么有用,所以没有包括在内 .1在C中它是bool .