這裏是一個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有關。
這裏是一個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有關。
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)
。
sizeof
運算符是一個編譯器函數(例如,在編譯時計算爲常量)。
sizeof(a,b)
就像sizeof(b)
)
sizeof沒有評估它的操作數是不真實的,它在預處理過程中評估它,但操作數不包含在生成的二進制文件中,它被替換爲一個數字。如果你輸入'printf(「%d \ n」,sizeof(a + b));'你可以看到你得到結果4,因爲操作數是根據整數提升和平衡規則進行評估的。 – Lundin
@Lundin:這不是評估操作數,只是解析它。我們知道添加一個int和一個char的結果是int,而沒有執行加法本身。見6.5.3.4/2(它也指出我需要編輯我的答案...) –