簡體   English   中英

C和C ++編譯器為以下代碼提供不同的消息,為什么?

[英]C and C++ compiler give different messages for the following code, why?

我被要求在面試中提供以下代碼的輸出。

int a[] = {1,2,3,4,5};
int *p = &a + 1;
printf("%d, %d", *(a+1), *(p - 1));

我說我無法確定第二個結果,所以我沒能通過采訪。

當我回到家中並嘗試編譯代碼時,g ++會報告錯誤,但gcc只會發出警告。 打印結果為“2,5”。

任何人都知道為什么C和C ++編譯器在這方面表現不同?

a是一個整數數組,在需要時轉換為指向第一個元素的指針。 a+1調用該轉換,並給出指向第二個元素的指針。

&a是指向數組本身的指針,而不是指向它的第一個元素,所以&a + 1指向數組的末尾(如果它是二維數組,則指向第二個數組的位置)。

然后代碼將該指針(類型為int (*)[5] )轉換為指向整數的指針(類型為int* )。 沒有顯式的reinterpret_cast ,C ++不允許這樣的轉換,而C在它允許的指針轉換中更寬松。

最后(假設pp2應該是相同的), p - 1指向a的最后一個元素。

好吧, a是5個整數的數組,所以&a是指向5個整數數組的指針。 在C ++中,你不能在沒有強制轉換的情況下在int*分配該地址。 gcc(用C語言)只給出警告,但我認為這不是有效的C.

對於代碼:

&a+1是之后的下一個陣列a ,這意味着,在第6元素的地址a ,所以p-1是第5元素的地址a

(我不確定&a+1是否合法。它是在數組之后的元素的地址,這通常是合法的,但是因為&a不是數組,所以它可能是非法的。)

int a[] = {1,2,3,4,5};
int *p = &a + 1;

這是無效的C代碼。

表達式&a + 1的類型為int (*)[5] 您不能將int (*)[5]類型的表達式賦給int *

除了通用對象指針類型void * ,對象指針之間沒有隱式轉換。 使用&a + 1值初始化p需要強制轉換。

C在哪里說這個聲明無效?

int *p = &a + 1;

在賦值運算符的約束中:

(C99,6.5.16.1p1)“兩個操作數都是兼容類型的限定或非限定版本的指針,左邊指向的類型具有右邊指向的所有類型的限定符”

並且int和數組類型不是兼容類型(有關類型兼容性的更多信息,請參閱6.2.7p1)。

同樣,它是初始化而不是賦值,但適用相同的約束:

(C99,6.7.8p11)“標量的初始值設定項應該是單個表達式,可選地用大括號括起來。對象的初始值是表達式的初始值(轉換后);與簡單賦值相同的類型約束和轉換apply,將標量的類型作為其聲明類型的非限定版本。“

C ++編譯器給出了一個錯誤,因為&a求值為int(*)[5] ,這是一個指向5個整數的指針,並且你試圖將它分配給一個int*

如果您確實修復了類型,則此代碼將打印數組中的第二項,然后是數組的地址。

我的猜測是C將數組衰減成指針,導致&a評估為int** ,並允許將其分配給int* 但是,我沒有做太多的C,所以其他人可能會更清楚。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM