【问题标题】:what is the order of execution, associativity in c? [duplicate]c中的执行顺序,关联性是什么? [复制]
【发布时间】:2013-12-20 09:38:27
【问题描述】:

为什么变量cd 的输出不同?我该如何解释e?谁能给点线索?

 #include <stdio.h>
 #include <string.h> 

 main()
 {
    int i=10,d=10,e=10;
    float c;
    c=(float)++i + ++i;
    d= ++d  + ++d;
    e= ++e  + ++e + ++e;
    printf("d=%d\n c=%f\n e=%d ",d,c,e);       
 }

这是输出。

d=24
c=23.000000
e=37

【问题讨论】:

    标签: c unary-operator


    【解决方案1】:

    为什么变量 c 和 d 的输出不同?

    因为程序的Undefined Behavior。声明

    c=(float)++i + ++i;  
    

    正在尝试在两个sequence point 之间修改i 两次。两个序列点之间的修改只能对一个变量进行一次。

    C-FAQ: 3.8:

    在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值。

    C11:5.1.2.3 程序执行:

    在表达式 A 和 B 的求值之间存在一个序列点意味着与 A 相关的每个值计算和副作用都在与 B 相关的每个值计算和副作用之前排序。

    语句相同

    d= ++d  + ++d;            //Modifying d three times
    e= ++e  + ++e + ++e;      //Modifying e four times
    

    旁注:

    C11:附录 C:序列点:

    以下是5.1.2.3中描述的顺序点:
    — 在函数指示符的评估和函数中的实际参数之间 通话和实际通话。 (6.5.2.2).
    — 在以下运算符的第一个和第二个操作数的计算之间: 逻辑与 &amp;&amp; (6.5.13);逻辑或|| (6.5.14);逗号, (6.5.17)。
    — 在条件 ?: 运算符的第一个操作数的计算和 计算第二个和第三个操作数中的任何一个 (6.5.15)。
    — 完整声明符的结尾:声明符 (6.7.6);
    — 在完整表达式的评估和下一个完整表达式之间 评估。以下是完整的表达式: 不属于 a 的初始化器 复合文字(6.7.9);表达式语句中的表达式 (6.8.3);这 控制选择语句的表达(ifswitch)(6.8.4);这 whiledo 语句的控制表达式 (6.8.5);每个(可选) for 语句的表达式 (6.8.5.3); return 中的(可选)表达式 声明 (6.8.6.4)。
    — 紧接在库函数返回之前 (7.1.4)。
    — 在与每个格式化输入/输出函数转换相关的动作之后 说明符(7.21.6、7.29.2)。
    — 在每次调用比较函数之前和之后,以及 也在对比较函数的任何调用和对象的任何移动之间 作为参数传递给该调用 (7.22.5)。
    §

    【讨论】:

      猜你喜欢
      • 2015-09-16
      • 1970-01-01
      • 2019-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 1970-01-01
      相关资源
      最近更新 更多