c - 如何确定逻辑表达式中函数调用的顺序
问题描述
我对函数调用的顺序感到困惑。我已经列出了我尝试过的命令,但仍然得到错误的答案。
!!!答案是“i 和 j 值未定义”。
根据运算符优先级:</h3>
- 如果编译器从左到右计算值
int i = (1+0) || (ignored); //1
int j = (1) || (ignored); //1
- 如果编译器首先计算'+'之后的值,则从左到右计算其他值
int i = (0+0) || (1); //1
int j = (2) || (ignored); //1
- 如果编译器从左到右计算值
int i = (1+0) || (ignored); //1
int j = (1) || (ignored); //1
- 如果编译器首先计算'+'之后的值,则从左到右计算其他值
int i = (0+0) || (1); //1
int j = (2) || (ignored); //1
我仍然得到错误的结论。
所以我尝试不遵守运算符优先级
- 如果编译器首先从右到左计算值
int i = (1+1) || (0); //1
int j = (ignored) || (2+2); //1
- 如果编译器只首先计算'+'之前的值,则从右到左计算其他值
int i = (0+1) || (0); //1
int j = (ignored) || (1+2); //1
我仍然得到错误的结论。
我再次猜测编译器可能不会忽略 || 之后的表达式 即使左边是真的
- 如果编译器从左到右计算值
int i = (1+0) || (1); //1
int j = (2) || (2+3); //1
- 如果编译器首先计算'+'之后的值,则从左到右计算其他值
int i = (0+0) || (1); //1
int j = (2) || (3+3); //1
- 如果编译器首先从右到左计算值
int i = (1+1) || (0); //1
int j = (3) || (2+2); //1
- 如果编译器只首先计算'+'之前的值,则从右到左计算其他值
int i = (0+1) || (0); //1
int j = (3) || (1+2); //1
我仍然得到错误的结论。
#include<stdio.h>
int x = 0;
int f(){
if(x == 0) return x + 1;
else return x - 1;
}
int g(){
return x++;
}
int main(){
int i = (f() + g()) || g();
int j = g() || (f() + g());
}
不管顺序如何,除了 i=1 和 j 的值是 1 之外,我的
答案是 i 和 j 的值是未定义的。
我想知道哪种情况会导致另一个输出......
原谅我的愚蠢......
解决方案
我们来分析一下i
。请注意,仅当左侧参数为 0 时才计算||
的第二个参数。
i
即使未指定获得此结果的方法,也始终为 1 。
这里没有未定义的行为。(正式地说,这是因为函数调用是一个有序的步骤。)
该语言没有指定在左侧评估中调用f()
和调用的顺序。g()
这留给实施。正式地,它甚至没有定义实现,因为不需要实现来记录行为。如果f()
首先调用,则 的值f() + g()
非零。如果g()
首先被调用f() + g()
,则为零,所以g()
再次被调用,这也是非零的,因为x
此时为 1。
j
||
由于仅评估的左侧,因此以 1 的形式退出。
一个更有趣的变体是
int f(){
if(x == 0) return ++x;
else return --x;
}
实际上不同的实现可能会为i
or返回 0 或 1 j
。
推荐阅读
- python - 从图像中删除特定颜色
- flutter - Flutter 提供的字体系列的完整列表?
- google-apps-script - 从 Google Apps 脚本访问链接的 Google 表格单元格
- javascript - 如何在Javascript中将字符串转换为json
- c - 求 MxM 矩阵的逆矩阵 - 使用 gauss-jordan 消元法
- node.js - 如何在MongoDB中聚合不同的数组字段
- docker - Dockerfile:命令在 Dockerfile 中有效,但在 shell 脚本中无效
- mongodb - mongoDB 中是否有一种有效的方法来获取组合结果文档?
- javascript - 你能用受控组件 React 控制虚拟 DOM
- javascript - 无法使用 Node Js 从 HTML 表单中获取输入