- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
三元运算符是否可以有一个空白的第二个或第三个参数,或者有一个非上下文特定的并且意味着“什么都不做”的参数?在下面的例子中,我想要一个三元运算符将一个整数变量乘以二,如果它是偶数,否则什么也不做。对于第三个参数,除了自赋值、加或减零、乘以或除以 1 之外,我想不出任何其他东西。无论如何,它们都是特定于上下文的。我想要一些对所有三元运算符都意味着“什么都不做”的东西。我尝试将参数留空,但无法编译。
#include <iostream>
int main()
{
int x = 5;
(x % 2 == 0) ? x *= 2 : x = x; // or x += 0, x -= 0, x *= 1, or x /= 1
std::cout << x << std::endl;
return 0;
}
有没有不涉及重述已经存在的变量、函数或对象的解决方案?例如,考虑两个函数 foo
和 goo
,其中 foo
返回一个 bool
。假设由于某些原因(例如后续调用的状态更改)无法再次调用这两个函数。
int main()
{
( foo() ) ? goo() : ; // won't compile
return 0;
}
最佳答案
如果你打算使用三元运算符,你可能想要分配它的结果:
x = (x % 2 == 0) ? 2 * x : x;
就个人而言,我认为我只需要使用一点点数学:
x <<= ((x & 1) ^ 1);
x&1
给出 x
的最低有效位,如果 x 为奇数则为 1,如果为偶数则为 0。 ^ 1
部分翻转该位,因此如果 x
是偶数,它给出 1,如果 x
是奇数,它给出 0。然后我们将 x
左移那么多位。移动 0 位显然会使 x
保持不变。左移一位将 x
乘以 2。
至于为什么后者会(或至少可能)更可取,这主要归结为一个问题,即您是否真的关心这种情况下的性能。如果您处在性能无关紧要的情况下,那么 if ((x%2)==0) x *= 2;
可能是您的最佳选择。
我至少猜到这个问题的至少部分原因是对效率的关注。如果是这样,纯数学方法可能是更好的选择。例如,让我们考虑一下 VC++ 为两者生成的代码:
; mathematical version:
mov eax, DWORD PTR _x$[esp-4]
mov ecx, eax
not ecx
and ecx, 1
shl eax, cl
[注意:对于此源代码,g++ 生成几乎相同的目标代码]。
忽略从内存加载 x
的(可能的)时间,这应该在任何 Intel 处理器上执行不超过 4 个时钟周期,回到 386 左右。更好的是,我d 期望任何处理器的任何编译器都能产生非常相似的结果——对于几乎任何合理的处理器来说,从源代码到汇编语言的直接、直白的翻译将在四个指令中完成实际的数学运算,每条指令大约是尽可能简单和快速。
使用if
语句的版本是这样的:
; Line 2
mov ecx, DWORD PTR _x$[esp-4]
mov eax, ecx
and eax, -2147483647 ; 80000001H
jns SHORT $LN5@f
dec eax
or eax, -2 ; fffffffeH
inc eax
$LN5@f:
lea eax, DWORD PTR [ecx+ecx]
je SHORT $LN1@f
; Line 3
mov eax, ecx
$LN1@f:
随着编译的进行,这还算不错。它至少避免了 div
,这将是实现 %2
的明显方式。不幸的是,它仍然不够聪明以具有竞争力——它仍然有几个分支,其中一个可能不是很容易预测,所以大约一半的时间我们会为预测错误的分支付出代价。
根据编译器的不同,您可以(并且将会)看到比这更好的结果。例如,改用 g++,我得到这个:
mov eax, DWORD PTR [ebp+8]
and eax, 1
test eax, eax
jne L2
sal DWORD PTR [ebp+8]
L2:
mov eax, DWORD PTR [ebp+8]
虽然这段代码肯定比 VC++ 做得更好,但它仍然远不及数学版本那么好。特别是,除非最低有效位是相当可预测的偶数或奇数,否则该分支可能有大约一半的时间被误预测。
底线:在最好的情况下,这可能接近匹配数学版本——但这将取决于编译器和输入数据的配合。除了编译器和输入数据的最偶然组合之外,它几乎肯定会慢至少 2 倍,而 10 倍甚至不会让人感到意外。
当然,根据我使用的标志、编译器版本等,我可能能够从任一编译器中获得比实际更好的结果。如果坚持不懈,我可能甚至会得到与代码的数学版本相同的结果。除非我非常了解目标编译器和 CPU,否则我什至不确定能否获得同样好的结果——而且我认为它们变得更好的可能性充其量是极其渺茫的。
关于c++ - 三元运算符的第二个或第三个参数为空白或什么都不做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18668882/
Or 运算符 对两个表达式进行逻辑“或”运算。 result = expression1 Or expression2 参数 result 任意数值变量。 expression1 任意
Not 运算符 对表达式执行逻辑非运算。 result = Not expression 参数 result 任意数值变量。 expression 任意表达式。 说明 下表显示如何
Is 运算符 比较两个对象引用变量。 result = object1 Is object2 参数 result 任意数值变量。 object1 任意对象名。 object2 任意
\ 运算符 两个数相除并返回以整数形式表示的结果。 result = number1\number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
And 运算符 对两个表达式进行逻辑“与”运算。 result = expression1 And expression2 参数 result 任意数值变量。 expression1
运算符(+) 计算两个数之和。 result = expression1 + expression2 参数 result 任意数值变量。 expression1 任意表达式。 exp
我对此感到困惑snippet : var n1 = 5-"4"; var n2 = 5+"4"; alert(n1); alert(n2); 我知道 n1 是 1。那是因为减号运算符会将字符串“4”转
我想我会得到 12,而不是 7。 w++,那么w就是4,也就是100,而w++, w 将是 8,1000;所以 w++|z++ 将是 100|1000 = 1100 将是 12。 我怎么了? int
Xor 运算符 对两个表达式进行逻辑“异或”运算。 result = expression1 Xor expression2 参数 result 任意数值变量。 expression1
Mod 运算符 两个数值相除并返回其余数。 result = number1 Mod number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
Imp 运算符 对两个表达式进行逻辑蕴涵运算。 result = expression1 Imp expression2 参数 result 任意数值变量。 expression1 任
Eqv 运算符 执行两个表达式的逻辑等价运算。 result = expression1 Eqv expression2 参数 result 任意数值变量。 expression1 任
我有一个运算符重载的简单数学 vector 类。我想为我的运算符(operator)获取一些计时结果。我可以通过计时以下代码轻松计时我的 +=、-=、*= 和/=: Vector sum; for(s
我是用户定义比较运算符的新手。我正在读一本书,其中提到了以下示例: struct P { int x, y; bool operator、运算符<等),我们
在 SQL 的维基百科页面上,有一些关于 SQL 中 bool 逻辑的真值表。 [1] 维基百科页面似乎来源于 SQL:2003 标准。 等号运算符 (=) 的真值表与 SQL:2003 草案中的 I
我遇到了一个奇怪的 C++ 运算符。 http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f
我正在阅读关于 SO 和 answers 中的一个问题,它被提到为: If no unambiguous matching deallocation function can be found, pr
我偶然发现了这个解决方案,但我无法理解其中到底发生了什么。谁能解释一下! 据我了解,它试图通过计算一半的单元格然后将其加倍来计算 a*b 网格中的单元格数量。但是我无法理解递归调用。 请不要建议其他解
Go的基本类型 布尔类型bool 长度:1字节 取值:布尔类型的取值只能是true或者false,不能用数字来表示 整型 通用整型 int / uint(有符号 / 无符号,下面也类似) 长度:根据运
在本教程中,您将学习JavaScript中可用的不同运算符,以及在示例的帮助下如何使用它们。 什么是运算符? 在JavaScript中,运算符是一种特殊符号,用于对运算数(值和变量)执行操作。例如,
我是一名优秀的程序员,十分优秀!