c - 我对 C 中的优先规则有疑问
问题描述
在以下函数中:
int fun(int *k) {
*k += 4;
return 3 * (*k) - 1;
}
void main() {
int i = 10, j = 10, sum1, sum2;
sum1 = (i / 2) + fun(&i);
sum2 = fun(&j) + (j / 2);
}
你会得到 sum 1 等于 46,sum 2 等于 48。如果没有优先规则,函数将如何运行?
如果没有一致的优先规则,事情会有多大的不同?
解决方案
优先规则告诉我们一个表达式是如何构造的,而不是它是如何计算的。在sum1 = (i / 2) + fun(&i);
中,规则告诉我们的内容包括:
i / 2
被组合在一起,因为它在括号中;例如,它不能形成(sum1 = i) / 2 + fun(&i);
。(i / 2)
和fun(&i)
被组合在一起是因为+
优先级高于=
, 使sum1 = ((i / 2) + fun(&i);
而不是(sum1 = (i / 2)) + fun(&i);
。
优先规则并没有告诉我们是否先评估i / 2
或fun(&i)
先评估。事实上,C 标准中没有任何规则指定是否先评估i / 2
or 。fun(&i)
编译器可以选择。
如果i / 2
先评估,结果将是10 / 2 + 41
然后5 + 41
和最后46
。如果fun(&i)
首先评估,结果将是14 / 2 + 41
然后7 + 41
和最后48
。您的编译器选择了前者。它本可以选择后者。
如果没有优先规则,函数将如何运行?
如果没有规则,我们将不知道函数将如何执行。规则告诉我们它将如何执行。
一些评论断言这个程序的行为是未定义的。这是不正确的。这种误解来自 C 2018 6.5 2,它说:
如果标量对象的副作用相对于同一标量对象的不同副作用或使用同一标量对象的值的值计算是未排序的,则行为未定义......</p>
在您的代码中,i / 2
使用i
并包含对(通过赋值更改其值)fun(&i)
的“副作用” 。i
如果这些是未排序的,则行为将是未定义的。但是,在计算参数之后fun
和调用它之前都有一个序列点,并且在每个完整表达式之后都有一个序列点fun
,包括它的return
语句。i
因此,对它的使用和副作用有一些排序。这种排序不完全由 C 标准的规则确定,但按照标准的定义,它是不确定排序的,而不是未排序的。
推荐阅读
- javascript - eventListener 在 javascript 中向下滚动/更改属性后停止工作
- python - 无法从 Tweepy 获取位置或名称
- django - 如何让我的句柄函数使用正确的参数运行,(Django,引导脚本)
- javascript - 如何将日期从一个时区转换为另一个时区
- angular - 如何将 cURL 命令转换为 Angular 的 http 请求?
- anaconda - Biopython for Anaconda on OSX“No module named 'Bio'”错误
- python - 在数据框中查找列表的共享成员的最有效方法是什么?
- http - 我可以使用哪些策略来克服网络限制?
- python - Pyspark - 删除组的重复并保留第一行
- tensorflow - 张量流中二元交叉熵的标签平滑