gpt4 book ai didi

c - 为什么 sum1 = 46 而 sum2 = 48

转载 作者:行者123 更新时间:2023-11-30 18:09:55 25 4
gpt4 key购买 nike

在下面提到的代码中,当运算符从左到右优先时,sum1 变量的答案是 46。但是在 sum2 中,答案是 48,并且优先级是从右到左。为什么这些答案变得不同。

#include <stdio.h>

int func(int *k){
*k+=4;
return 3 * (*k)-1;
}

void main() {
int i = 10, j = 10, sum1, sum2;
sum1 = (i / 2) + func(&i);
sum2 = func(&j)+(j/2);
printf("%d\n",sum1);
printf("%d",sum2);
}

最佳答案

在表达式 (i/2) + func(&i) 中,编译器(或一般的 C 实现)可以自由地首先计算 i/2 或首先是func(&i)。同样,在 func(&j) + (j/2) 中,编译器可以自由地首先评估 func(&j)j/2 .

优先级无关紧要。优先级告诉我们表达式是如何构造的,但它并不能完全确定其求值的顺序。优先级告诉我们,在a * b + c * d中,结构必须是(a * b) + (c * d)。在 a + b + c 中,优先级以 + 从左到右关联的形式告诉我们结构必须是 (a + b) + c.它没有告诉 a 必须在 c 之前计算。例如,在a() + b() + c()中,结构是(a() + b()) + c(),但是编译器可以按任何顺序调用函数,如果需要,将其结果保存在临时寄存器中,然后添加结果。

func(&j)+(j/2)中,没有从右到左的优先级或关联。 C 标准中没有规则规定 j/2 必须在 func(&j) 之前计算。

在没有其他约束的情况下,编译器可能倾向于从左到右计算子表达式。然而,各种因素可能会改变这一点。例如,如果一个子表达式出现多次,编译器可能会尽早计算它并保留其值以供重用。本质上,编译器构建一个树结构来描述它需要评估的表达式,然后寻找评估它们的最佳方法。它不一定从左到右进行,并且您不能依赖任何特定的评估顺序。

有关测序的问题

C 标准在 C 2018 6.5 2 中有一条规则,规定是否对对象进行修改,如语句 *k+=4; 中的 i 所发生的那样;,相对于使用同一对象的值计算而言是无序的,如 i/2 中的 i 所发生的那样,则行为未定义。然而,这个问题在这段代码中不会发生,因为修改和值计算是不确定地排序的,而不是无序的:6.5.2.2 10说“......调用函数(包括其他函数调用)中的每个评估之前没有专门排序或者在被调用函数体的执行相对于被调用函数的执行不确定地排序之后。” C 5.1.2.3 3 说“……当 A 在 B 之前或之后排序时,评估 A 和 B 是不确定地排序,但未指定是哪一个……”

关于c - 为什么 sum1 = 46 而 sum2 = 48,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60009483/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com