数组的地址是否等于C ++中第一个元素的地址?

时间:2015-11-11 09:11:43

标签: c++ arrays language-lawyer memory-address

由于WG14 / N1570中的以下句子,可以在C中保证:

  

6.2.5 / 20 ...数组类型描述了具有特定成员对象类型的连续分配的非空对象集,称为元素类型。

但是在WG21 / N4527中,即在C ++中,相应的句子变为

  

8.3.4 / 1 ...数组类型的对象包含一个连续分配的非空N个子类型的T类型。

而“describe”一词改为“contains”,这不能保证数组的地址等于第一个元素的地址。这种改变是故意的还是无意的?如果是故意的,那么数组的地址是否等于C ++中第一个元素的地址?如果确实如此,C ++标准中的哪一段可以保证这一点?

3 个答案:

答案 0 :(得分:4)

在C ++中,它由4.2 / 1数组到指针转换[conv.array]保证,(由我粗体显示)

  

“N T数组”或“未知数组的数组”的左值或右值   T“可以转换为”指向T“的prvalue类型。 结果   是指向数组第一个元素的指针。

这意味着如果你想在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指向同一地址。

答案 1 :(得分:4)

我不认为它在任何地方明确说明,但我认为它来自5.3.3 Sizeof

  

n个元素数组的大小是元素大小的n倍

可以存储在数组起始地址的唯一内容是数组的第一个元素。

答案 2 :(得分: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]);
}

这将始终报告两个指针相等。 songyuanyao解释了原因。

但是,x实际上并不是指向数组的指针(也不是在此代码中转换为1)。如果您将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()
}