【问题标题】:Is this program having any sequence point issues?这个程序有任何序列点问题吗?
【发布时间】:2011-04-05 03:31:15
【问题描述】:
#include<stdio.h>
 int main()
 {  
       int i=7,j;
       j=(i++,++i,j*i); 
       return 0;
}

j=(i++,++i,j*i);这个定义好了吗?让我清除我的疑问。

【问题讨论】:

  • 为什么要做这样的事情?你就不能i += 2; j *= i吗?
  • @JeremyP: 只是为了学习 c 概念 :-)
  • 谁在乎。您永远不会在现实生活中看到此代码。它不会通过代码审查,因为您必须解释序列点是什么,而 80% 的开发人员不知道什么是序列点。
  • 看看马丁怎么说?所有这些晦涩难懂的行为与现实世界中的编程完全无关。要涵盖所有这些内容,您唯一需要知道的是要非常小心带有副作用的表达式。

标签: c operator-precedence sequence-points


【解决方案1】:

在您的代码中,“,”将用作序列点。

所以在这个

j=(i++,++i,j*i);

表达式将从左到右工作。
所以首先 i++ 然后 ++i 然后 j*i

最后 j*i 将存储在 j 中;

但最后你的结果会很优雅,因为“j”没有预定义的数据
所以未定义的值将存储在 j 中。

如果你不使用“()”

您的代码将作为单个语句工作,例如

j=i++;
++i;
j*i;

【讨论】:

    【解决方案2】:

    这个表达式没问题,因为comma operatorsequence point

    (i++, ++i, j*i)
    

    但是,不要将它与逗号不充当序列点的以下内容混淆:

    somefunction(i++, ++i, j*i)
    

    那么 j = i++ * ++i

    乘法运算符不是序列点。


    (请原谅我劫持了你的答案)

    来自 ISO 9899:1999(C 标准)的 §3.4:

    3.4 行为

    外观或动作

    3.4.1 实现定义的行为

    每个实现都记录了如何做出选择的未指定行为

    示例 实现定义行为的一个示例是高位的传播 当有符号整数右移时。

    3.4.2 特定于语言环境的行为

    行为取决于每个人的国籍、文化和语言的当地惯例 实施文件

    示例 特定于语言环境的行为的示例是 islower 函数是否为 26 个小写拉丁字母以外的字符。

    3.4.3 未定义行为

    行为,在使用不可移植或错误的程序结构或错误数据时, 本国际标准对此没有要求

    注意 可能的未定义行为包括完全无视情况和不可预测 结果,在翻译或程序执行期间以文件的方式表现 环境(有或没有发出诊断消息),终止翻译或 执行(发出诊断消息)。

    示例 未定义行为的一个示例是整数溢出行为。

    3.4.4 未指明的行为

    本国际标准提供两种或多种可能性的行为,并且 对在任何情况下选择哪个都没有进一步的要求

    示例 未指定行为的一个示例是函数参数的顺序 评估。

    【讨论】:

    • 是的!评估顺序取决于实现。
    • @Jagan,我认为这实际上是未定义的行为。
    • unspecified , undefined 和 implementationdependent。这些术语非常危险。我可以互换使用它们(我不应该这样做)。如果你解释这些词,我会感觉更好。
    • @Jagan:请参阅标准中的引用。
    【解决方案3】:

    是的,定义明确。 sequence point

    comma operator in C

    【讨论】:

    • 未定义。表达式内部没有序列点,i 被修改了两次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多