2015-11-11 47 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

相关问题