2013-04-29 102 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

相關問題