本文介绍了为什么C没有逻辑赋值运算符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要编写以下形式的声明

I had the need to code a statement of the form

a = a || expr;

应评估expr的位置,并且未设置将结果分配给a的情况,前提是未设置a.这取决于逻辑或的短路能力.

where expr should be evaluated and the result be assigned to a iff a is not set. this relies on the logical OR's short-circuiting capabilities.

当然,较短的写法是

a ||= expr;

但是(令我惊讶的是)C没有逻辑赋值运算符.

but (to my surprise) C does not have logical assignment operators.

所以我的问题是双重的.首先,是否有较短的方法可以在标准C中编写第一个语句(三元运算符甚至更糟-a = a ? a : expr要求我将a拼写三次).

So my question is twofold. First, is there a shorter way to write the first statement in standard C (the ternary operator is even worse - a = a ? a : expr requires me to spell out a thrice).

第二,为什么C中没有逻辑分配?我想到的可能原因是:

Secondly, why aren't there logical assignments in C? The possible reasons I could think of are:

  • 它使语法更难解析吗?
  • 在这些情况下,处理短路有细微之处吗?
  • 它被认为是多余的(但这不是反对所有运算符分配的论点吗?)

编辑

请解锁此问题,因为:

  • 与该问题相关的问题(被指控为重复)尚未得到答复.该问题的(接受)答案表明不存在||=,因为它重复了|=的功能.那是错误的答案. |=不会短路.

  • The question it has been linked to (as a alleged duplicate of) HAS NOT BEEN ANSWERED. The (accepted) answer to that question states that ||= is not present because duplicates the functionality of |=. That is the wrong answer. |= does not short-circuit.

C和C ++是不同的语言.我想知道为什么C没有它.实际上,诸如C ++尤其是Java的派生语言(没有像Edmund的回答所建议的那样受遗留代码问题的困扰)这一事实使这个问题变得更加有趣.

C and C++ are NOT the same languages. I wish to know why C doesn't have it. In fact, the fact that derived languages like C++ and, particularly, Java (which did not suffer from the problems of legacy code as has been suggested in Edmund's answer) makes the question even more interesting.

编辑2

现在看来我的初衷是错误的.在语句a = a || expr中(其中a是整数,而expr返回整数值),首先aexpr都将隐式转换为布尔值",然后将分配布尔值"值到a.这将是不正确的-整数值将丢失.谢谢Jens和Edmund.

It now seems like my original intent was wrong. In the statement a = a || expr (where a is integral and expr returns an integral value, first both a and expr will be implicitly converted to "booleans", and then the "boolean" value will be assigned to a. This will be incorrect — the integral value will be lost. Thanks, Jens and Edmund.

因此,对于问题的第一部分,编码我的意图的正确方法(而非替代方法:)将会是:

So for the first part of the question, the correct ways, not alternatives :), to code my intention would be:

if (!a) a = expr;

a = a ? a : expr;

尽管我个人更喜欢第一个(因为键入的a少了一个),但它们应该被优化为相同的(我认为).

they should be optimized the same (I think) though personally I would prefer the first one (because it has one less a to type).

但是,问题的第二部分仍然存在.詹斯(Jens)和埃德蒙(Edmund)关于a ||= expr中的歧义的论点同样适用于a = a || expr.分配案例可以简单地视为普通案例:

However, the second part of the question still remains. The arguments that Jens and Edmund about have given about the ambiguity in a ||= expr apply equally well to a = a || expr. the assignment case can simply be treated as the normal one:

  • a转换为布尔值
  • 如果为true,则整个表达式的值将等于a的布尔值.
  • 否则评估expr,将结果转换为布尔值,分配给a,然后将其返回
  • convert a to boolean
  • if it is true, the value of the entire expression becomes equal to the boolean value of a
  • otherwise evaluate expr, convert result to boolean, assign to a, and return it

在分配和正常情况下,上述步骤似乎都是相同的.

The steps above seem to be the same for both the assignment and normal case.

推荐答案

a ||= expr由于对等效的a = a || expr进行了短路评估而存在问题.

a ||= expr is problematic due to short circuit evaluation of its equivalent a = a || expr.

要具有像a = a || expr这样的a ||= expr功能,请考虑OP的断言:

To have a ||= expr function like a = a || expr consider OP's assertion:

这不是很正确.如果a评估为true,则不会转换expr.如果exprscanf()rand()之类的东西或影响程序状态的某些功能,则将有所不同.

This is not quite correct. expr will not be converted if a evaluates to true. This would make a difference should expr be something like scanf() or rand() or some function that affected the state of the program.

诸如a ||= scanf("%d", &i) != 1;的代码将仅尝试扫描a中具有错误值的数据.尽管可以通过这种方式扩展语言,但是对当前的||&&集合使用更多的短路运算符可能会导致比清晰的简化更多的编码问题.

Code such as a ||= scanf("%d", &i) != 1; would only attempt to scan data with a false value in a. Although it would be possible to extend the language this way, additional short-circuit operators to the current set of || and && would likely cause more coding problems than clear simplifications.

另一方面:一种快速(如果混淆)的代码编写方法,其中函数会在错误时返回非零代码.

On the other hand: A quick, if obfuscated, way to write code where functions return non-zero codes on error.

// Perform functions until an error occurs.
bool error = foo1();
error &&= foo2();  // Only valid if C was extended with &&=
error &&= foo3();

这篇关于为什么C没有逻辑赋值运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 00:56