关于评价顺序与比较的几个问题 在C/C++面试中,我发现了一些我没有正确回答的问题,我用Visual C++来检查结果,希望你能帮助我理解:
(一) 当我在5.2中添加一个float cast时,它可以工作 (三)关于评价顺序与比较的几个问题 在C/C++面试中,我发现了一些我没有正确回答的问题,我用Visual C++来检查结果,希望你能帮助我理解:,c++,boolean-expression,C++,Boolean Expression,(一) 当我在5.2中添加一个float cast时,它可以工作 (三) =>我认为我们总是返回0,因为我认为编译器会将“return x++”转换为:return x;x++;那么我们将永远不会执行增量…下次,当您有多个问题时,请分别提问 对问题1的回答: 有几件事: &&和|运算符都强制从左向右求值1,并且都引入了序列点;在计算右侧操作数之前,将计算左侧操作数并应用所有副作用 &&和|运算符都短路-如果表达式的值可以从左侧操作数确定,则不会计算右侧操作数 在表达式a | | b中,如果a为
=>我认为我们总是返回0,因为我认为编译器会将“return x++”转换为:return x;x++;那么我们将永远不会执行增量…下次,当您有多个问题时,请分别提问 对问题1的回答: 有几件事:
&&
和|
运算符都强制从左向右求值1,并且都引入了序列点;在计算右侧操作数之前,将计算左侧操作数并应用所有副作用&&
和|
运算符都短路-如果表达式的值可以从左侧操作数确定,则不会计算右侧操作数
- 在表达式
中,如果a | | b
为非零,则不会计算a
李>b
- 在表达式
中,如果a和&b
为零,则不会计算a
李>b
&
的优先级高于|
,因此a | | b&&c
被解析为a | |(b&&c)
x++
计算为x
的当前值,作为副作用增加x
++x
计算为当前值x
加1,作为副作用,增加x
++i && ++j || ++k
被解析为
评估结果如下:
++i
;结果是-2
不是零,因此:++j
进行评估;结果是3
,因此:-2
和3
均为非零,因此:++i&&++j
计算结果为1,因此:++k
根本不计算李>
对问题2的回答:
同样,有几个问题:
5.2
的类型为double
,而不是float
;要使其浮动,可以使用f
后缀-5.2f
float
和double
具有不同的表示形式(double将更多位用于指数和分数),因此它们将为相同的值存储不同的近似值,这就是为什么=
比较不起作用的原因==
来比较浮点值;通常,您将获取两个值之间的差值,并确保其小于某个ε值(请记住,ε值取决于大小)x++
的结果,但该表达式仍然具有递增x
的副作用(副作用在return
语句结束之前应用)
1.C中的大多数运算符不强制执行特定的求值顺序-给定像
a+b*C
这样的表达式,a
、b
和C
中的每一个都可以按任意顺序求值。必须知道b*c
的结果才能添加到a
的结果中,但这并不意味着b
或c
必须在a
之前进行评估bool myBool = (1 || 0+6*4);
myBool
将尽快进行评估。在本例中,它将计算为true,因为|
中的左参数为true。它立即停止评估。这同样适用于&&
。这就是为什么在布尔运算符的左侧添加更可能失败的情况是惯用做法
#include <iostream>
int main() {
double i = 0.1;
double total = 0.0;
for(int j = 0; j < 10000; j++) {
total+=i;
}
// total = 0.1*10000 = 1000... right?
std::cout << std::boolalpha << "total == 1000.0 ? " << (total == 1000.0) << std::endl;
return 0;
}
#包括
int main(){
双i=0.1;
双倍合计=0.0;
对于(int j=0;j<10000;j++){
总数+=i;
}
//总数=0.1*10000=1000…对吗?
标准::考特问题1:
&&
运算符的优先级高于|
,因此将首先对其求值。这两个术语(++i
和++j
)有预增量,所以它们分别增加到2和3,然后它们被加上。在C++中,0是“代码> false <代码>,其他的东西都是<代码>真的<代码>。在这种情况下,这两个术语都是<代码>真< /COD>(即,非零)。,所以&
返回true
。现在是测试true | |++k
的时候了。这里,一个优化开始了:因为true | | |任何
都将始终是true
,编译器甚至不测试表达式。也就是说,它不执行它。k
不会增加。这就是为什么它是一个非常糟糕的h如果语句执行某些操作,则可以将代码放在内部-您无法确定它是否会运行,具体取决于条件。如果需要运行,请确保它没有放在那里,或者可以将其优化掉
问题2:
浮点算术是很棘手的——精确地表示一个数字通常是不可能的,而真正使用的数字只是一个非常接近的近似值——足够接近它看起来是可行的,但是如果你仔细检查每一个细节,你会发现数字不是它们看起来的样子
++i && ++j || ++k
(++i && ++j) || ++k
bool myBool = (1 || 0+6*4);
#include <iostream>
int main() {
double i = 0.1;
double total = 0.0;
for(int j = 0; j < 10000; j++) {
total+=i;
}
// total = 0.1*10000 = 1000... right?
std::cout << std::boolalpha << "total == 1000.0 ? " << (total == 1000.0) << std::endl;
return 0;
}