[英]Why does cout and return give different values in the following c++ code?
[英]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在它允許的指針轉換中更寬松。
最后(假設p
和p2
應該是相同的), 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.