2011-08-09 50 views
0

這裏是一個C代碼片段sizeof操作符的解釋

char *p="Hello World"; 
int a; 
char b; 
printf("%d\n",sizeof(p++)); 
printf("%c\n",*p); 

printf("%d",sizeof(a,b)); 
printf("%d",sizeof(b,a)); 

這裏是輸出

4 
H 
1 
4 

任何人都可以解釋爲什麼還沒有P獲得遞增的,什麼是這裏使用逗號操作符的。我讀到它與VLA有關。

回答

10

p沒有得到增加,因爲sizeof不評估其操作數,它只是使用的類型表達方式。

sizeof是一個以單一表達式作爲操作數的運算符,而不是括號括起來的參數列表。因此,在sizeof(a,b)中,單個操作數是(a,b)。因此,sizeof(a,b)中的逗號是逗號運算符 - 與printf("%c\n", *p)中的逗號不同,逗號是參數分隔符而不是逗號運算符。

評估時,逗號運算符首先評估其左手側,然後評估右手側。操作員的結果是右側的結果。因此,雖然(a,b)未被評估,但表達式的類型是右側的類型。因此sizeof(a,b)相當於sizeof(b)。真的,這裏沒有「使用」逗號運算符,至少沒有用處。除了測試你的閱讀能力之外,這毫無意義。

它與VLAs(可變長度數組)無關。

與VLA有什麼關係是,當sizeof應用於VLA時,其定義爲評估表達式(C99中的6.5.3.4/2)。編譯時當然不知道VLA的大小。

但是,當在逗號運算符的RHS上使用時,VLA的名稱會像任何其他數組一樣衰變爲指針。這是6.3.2.1/3:有三種情況下數組不會衰減,「sizeof的操作數」就是其中之一,但「逗號操作符的RHS」不是。所以:

#include <stdio.h> 
int main() { 
    int a = 10; 
    int b[a]; // VLA 
    const char *p = "Hello"; 
    printf("%d\n", sizeof(++p, b)); 
    printf("%d\n", sizeof b); 
    printf("%c", *p); 
} 

打印(我的機器上):

4 
40 
H 

因爲在第一sizeof,即使有一個VLA的逗號操作符的RHS的sizeof操作數的類型int*,而不是VLA,因此(++p, b)未被評估。在第二個sizeof中,操作數的類型是VLA,其中評估,其大小爲10*sizeof(int)

+1

sizeof沒有評估它的操作數是不真實的,它在預處理過程中評估它,但操作數不包含在生成的二進制文件中,它被替換爲一個數字。如果你輸入'printf(「%d \ n」,sizeof(a + b));'你可以看到你得到結果4,因爲操作數是根據整數提升和平衡規則進行評估的。 – Lundin

+3

@Lundin:這不是評估操作數,只是解析它。我們知道添加一個int和一個char的結果是int,而沒有執行加法本身。見6.5.3.4/2(它也指出我需要編輯我的答案...) –

1

sizeof運算符是一個編譯器函數(例如,在編譯時計算爲常量)。

  1. 這意味着:p ++被忽略,只使用p的類型。
  2. 當有一個逗號,最後一個參數是用來(所以,例如sizeof(a,b)就像sizeof(b)
+2

'sizeof'並不總是在編譯時計算,例如,使用可變長度數組。 – dreamlax

+0

我沒有意識到這一點,謝謝。 (儘管它與這個問題無關) – MByD

+1

sizeof不是評估它的操作數,它在預處理期間評估它,但操作數不包含在生成的二進制文件中,它被替換爲數。如果你輸入'printf(「%d \ n」,sizeof(a + b));'你可以看到你得到結果4,因爲操作數是根據整數提升和平衡規則進行評估的。 – Lundin