gpt4 book ai didi

c - 如何根据操作数的顺序进行 C 赋值

转载 作者:太空宇宙 更新时间:2023-11-04 05:16:16 25 4
gpt4 key购买 nike

我敢肯定你们中的大多数人都知道 C 没有指定将计算运算符(例如 +)的哪些顺序操作数。

例如x = exp1 + exp2 的计算方式可能是首先计算 exp1,然后计算 exp2,然后将结果相加。但是,它可能会首先评估 exp2。

我如何进行 C 赋值,根据 + 的左操作数还是右操作数先求值,将 1 或 2 赋给 x?

最佳答案

编写这样一个表达式的问题是你不能在其中两次写入同一个变量,否则代码将调用未定义的行为,这意味着会有一个错误,任何事情都可能发生。如果一个变量在一个表达式中被修改,则不允许在同一个表达式中再次访问同一个变量,除非访问被所谓的序列点分隔。 (C11 6.5/2) See this for details .

所以我们不能写这样的代码:

// BAD CODE, undefined behavior
_Bool first=false;
x = (first?(first=true,exp1):0) + (first?(first=true,exp2):0);

此代码调用了未定义的行为,因为在表达式的不同位置之间对 first 的访问是未排序的。


但是,可以通过使用函数来实现类似的代码。每当调用一个函数时,在参数求值之后、函数被调用之前都有一个序列点。在函数返回之前还有另一个序列点。所以这样的代码是可能的:

n = expr(1) + expr(2)

这仅具有未指定的行为 - 因为 + 的操作数的评估未指定。但是任何地方都没有无序访问,这意味着代码不会崩溃等。我们根本无法知道或假设它会给出什么结果。示例:

#include <stdio.h>

static int first=0;

int expr (int n)
{
if(first == 0)
{
first = n;
return first;
}

return 0;
}

int main (void)
{
int n;
printf("%d\n", n = expr(1) + expr(2)); // unspecified order of evaluation
first=0;
printf("%d\n", n = expr(1) + expr(2)); // unspecified order of evaluation

return 0;
}

这在我的系统上给出了输出 1 1,但它也可能给出了输出 1 22 12 2。下次我执行该程序时,它可能会给出不同的结果 - 我们不能假设任何东西,除了该程序将以一种未记录的方式确定性地运行。

之所以没有明确说明,是因为它允许不同的编译器根据情况不同地优化它们的表达式解析树。这反过来又可以实现最快的执行时间和/或编译时间。

关于c - 如何根据操作数的顺序进行 C 赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49422018/

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