2015-11-11 48 views
3

這可以在C被保證,因爲在WG14/N1570下面的句子的:數組的地址是否等於C++中第一個元素的地址?

6.2.5/20 ...的陣列型描述了一種連續地分配非空的對象集與特定的成員對象類型,稱爲元素類型。

但在WG21/N4527,即,在C++中,對應的句子變得

8.3.4/1 ...陣列類型的對象包含N個子對象的連續分配的非空集合的類型T.

而單詞「describe」變成「contains」,這不能保證數組的地址等於它的第一個元素的地址。這種改變是有意的還是無意的?如果是故意的,數組的地址是否等於C++中第一個元素的地址?如果是這樣,C++標準中的哪一段可以保證這一點?

回答

3

我不認爲這是明確的任何地方說,但我相信它遵循從5.3.3 Sizeof:元素的大小

n個元素的數組的大小是n倍

可以存儲在數組起始地址的唯一東西是數組的第一個元素。

+0

就是這樣!謝謝! – xskxzr

4

在C++中它是由4.2/1陣列到指針轉換[conv.array],(由我粗體)

左值或類型的右值「陣列NT的」或「陣列保證T的未知範圍 「可以被轉換爲類型」指向T的指針「的前值。 結果 是指向數組的第一個元素的指針。

這意味着如果你想在C++中取一個數組的地址,你會得到一個指向數組的第一個元素的指針。即

int a[10]; 
int* p1 = a;  // take the address of array 
int* p2 = &a[0]; // take the address of the first element of the array 

標準保證p1p2將指向相同的地址。

+0

但是這並沒有說明數組的地址。它只是說一個數組(**既不是它的地址也不是指向這個數組的指針**)可以被轉換爲指向它的第一個元素的指針。即使它表示可以將指向數組的指針轉換爲指向其第一個元素的指針,它也不會說轉換使存儲在指針中的值保持不變。 – xskxzr

+0

@ Shenke我已經添加了一些解釋,因爲我對引用標準的理解。 – songyuanyao

+0

在你的例子中,數組的地址就是'&a'。所以我要問的是,(void *)(&a)==(void *)a'是否爲真。 – xskxzr

0

這取決於你所說的「陣列地址」。

如果你問一個數組是否在轉換爲指針時給出的結果等於它的第一個元素的地址,那麼答案是肯定的。例如;

#include <iostream> 

void func(int *x, int *y) 
{ 
    std::cout << "x and y are "; 
    if (p != q) std::cout << "NOT "; 
    std::cout << " equal\n"; 
} 

int main() 
{ 
    int x[2]; 

    func(x, &x[0]); 
} 

這將始終報告兩個指針是相等的。宋遠堯已經解釋了爲什麼。

但是,x實際上並不是一個指向數組的指針(在此代碼中也沒有轉換爲一個指針)。如果更改的func()main()調用

func(&x, &x[0]); 

那麼該語句甚至不會編譯。原因是&x(數組x的地址)不是指向int的指針 - 它是指向兩個int的數組的指針,並且不能隱式轉換爲指向int的指針。

但是,該值將與運行此代碼可能證明的值相同。

#include <iostream> 

void func2(void *x, void *y) 
{ 
    std::cout << "x and y are "; 
    if (p != q) std::cout << "NOT "; 
    std::cout << " equal\n"; 
} 

int main() 
{ 
    int x[2]; 

    func2(&x, &x[0]);  // both pointers implicitly converted to void * when calling func2() 
} 
+0

是的,我想問的是爲什麼存儲在兩個指針中的兩個值在最後一個代碼中是相同的。我想在C++標準中找到證據。 – xskxzr

+0

我目前的機器上沒有C++標準的副本,所以無法查找它。不過,我記得有一句話說''x'產生一個地址對應於'x'的內存中的起始點(即「開始」是指一個字節的最小地址,它是' x')。 – Peter

+0

是的,我知道這些話。但問題在於爲什麼數組的起點是它的第一個元素?在第一個元素之前,也許還有別的東西(填充,也許我不知道,或者是因爲標準允許,而沒有意義)。 – xskxzr

相關問題