[英]Pointer vs Array in function definition: what is the difference between void fct1(int *p) and void fct1(int p[])?
[英]When (void *) p == (void *) *p - What does the Standard say about this?
例子:
int a[99];
int (*p)[99] = &a;
// this prints 1
printf("%d\n", (void *) p == (void *) *p);
通常,如果p
是指向數組的指針,則p
和*p
的對象表示(即位模式)是相等的。
我只是失去了,完全不能確定這種行為的便攜性。
所以,我很好奇這種行為是否受到標准的保證。 如果是這樣,有人可以引用所有保證它的相關段落嗎?
此比較保證為 1。
C 標准的相關部分是關於相等運算符和指針比較的第 6.5.9p6 節:
兩個指針比較相等當且僅當它們都是空指針,都是指向同一個對象的指針(包括指向對象的指針和位於其開頭的子對象)或函數,都是指向同一數組最后一個元素之后的指針對象,或者一個是指向一個數組對象末尾的指針,另一個是指向另一個數組對象開頭的指針,該對象恰好緊跟地址空間中的第一個數組對象。
請特別注意粗體的段落。 這意味着兩件事:1)指向結構的指針和指向其第一個成員(合適的轉換)的指針將比較相等,2)指向數組的指針和指向其第一個成員的指針(再次,合適的轉換)將比較平等的。
在您的特定情況下, p
指向一個數組, *p
是數組本身,並且在表達式中使用*p
產生一個指向其第一個成員的指針。 兩者都轉換為void *
以賦予它們一個通用類型。 因此,這種比較將始終評估為 1。
通常,如果
p
是指向數組的指針,則p
和*p
的對象表示(即位模式)是相等的。
如果p
是指向數組的指針,則*p
是數組。 數組的位表示是數組元素的位表示的串聯(因為 C 2018 6.2.5 20 說數組由連續分配的對象組成)。 數組中的位通常不等於指針中的位。
但是,當數組在表達式中用作一元&
的操作數或sizeof
的操作數或用於初始化數組的字符串文字以外的表達式時,該數組會自動轉換為指向其第一個元素的指針。 數組*p
的第一個元素是(*p)[0]
,因此*p
會自動轉換為&(*p)[0]
。
那么問題是(void *) p
是否等於(void *) &(*p)[0]
。
C 2018 6.3.2.3 1 告訴我們任何指向對象類型的指針都可以轉換為void *
。 但是,當指針為void *
,它並沒有告訴我們比較的結果是什么。 它確實告訴我們,將void *
轉換回其原始類型會產生一個與原始類型相等的指針。
C 2018 6.5.9 6 告訴我們“兩個指針比較相等當且僅當……,兩者都是指向同一個對象的指針(包括指向對象的指針和開頭的子對象)……”(我省略了其他一些情況這里無關緊要。)給定兩個void *
我們該怎么做? 似乎意圖是讓指針“指向一個對象”,即使它當前是void *
的形式。 然后(void *) p
指向數組並且(void *) &(*p)[0]
指向其開頭的子對象,因此它們比較相等。
使用(char *) p == (char *) *p
的語義會更清晰,因為 C 2018 6.3.2.3 7 告訴我們轉換為char *
會產生一個指向對象第一個字節的指針,以及一個指向對象的第一個字節的指針。數組與其第一個元素的第一個字節相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.