2013-04-29 51 views
5

以下两个代码块是否完全相同,达到同样的事情吗?它显示了同样的事情,当我运行该程序,但我希望得到一些严谨的解释。类似于“for(i = 1; i <= 10; printf(”%d n“; i),i ++)在C中有效且无UB?

for(i=1;i<=10;i++) 
{ 
printf("%d\n",i); 
} 

for(i=1;i<=10;printf("%d\n",i),i++); 

for环路期望有效C语句作为参数,没有按是不是?但即使我已经在StackOverflow上验证过,像x+=4,y=x*2;这样的语句是安全的,因为逗号作为序列在这里指出,printf("%d\n",i),i++)作为在for循环上面的参数传递的陈述是相同的道理?

如果是,请懒得回答,从它出现的轻微问题:

  • 是否comma充当序列点涉及许多逗号一份声明中分离

    函数调用如下:

    printf("Enter number\n"),scanf("%d",&number),printf("You entered %d",number);

+4

是的,但你为什么要写这样的代码? (逗号是顺序点,只要它不是函数调用中的逗号)。 – nhahtdh 2013-04-29 12:07:43

+0

是的,它是好的。逗号运算符引入一个序列点。 – wildplasser 2013-04-29 12:07:43

+0

它是C标准的一部分..让我找到参考。 – 2013-04-29 12:08:03

回答

3

这是完全有效的,两个语句都与编译器相同。对于读者来说,第二个几乎是不可读的,所以这是唯一的区别。使用第二种格式几乎没有意义。

序列点由逗号运算符引入。

参考:

6.5.17逗号运算符

第2段:

逗号操作者的左操作数作为空隙表达式求值;在它的评估和右操作数的评估之间有一个 序列点。然后评估右边的 操作数;结果有它的类型和value.114)

+0

什么是技术原因,说下面的语句是荒谬的'int a,b,* ptr,printf(“Hello”),printf(“Howdy”);'?如果使用'(int a,b,* ptr),printf(“Hello”),printf(“Howdy”);'' – 2013-04-29 12:31:07

1

答案是在C标准的6.8.5.3

1774声明

for (clause-1 ; expression-2 ; expression-3) statement 

行为如下:

1775表达式>表达式-2是在每次执行循环体之前评估 的控制表达式。

1776在每次执行循环体之后,表达式-3被评估为空表达式 。

1777如果子句-1是一个声明,它声明的任何 标识符的范围是声明的剩余部分和整个循环,包括其他两个表达式;

1778在控制表达式的第一个 评估之前,按执行顺序达到它。

1779如果条款-1是一个表达式,它被评价为控制 expression.134的第一评估之前的空隙 表达)

1780两者子句-1和表达-3可以省略。

1781省略的表达式-2被非零常量替换。

在执行printf语句和增加i之间建立了一个序列点。在这种情况下,printf声明和iexpression-3,而不是条件声明,因此该声明有效,但不是最佳做法。

+0

什么是技术原因可以说下面的语句是荒谬的'int a,b,* ptr,printf(“Hello”),printf(“Howdy”);'?如果使用'(int a,b,* ptr),printf(“Hello”),printf(“Howdy”);'' – 2013-04-29 12:31:26

+0

@SheerFish:和我做的没有区别:'int a,b,c = 0;'逗号运算符的工作原理是一样的。我的例子中的差异是分配。尽管你的例子不太可读。 – 2013-04-29 12:34:18

+0

我应该把它放在另一个问题吗? – 2013-04-29 12:35:27

相关问题