由于WG14 / N1570中的以下句子,可以在C中保证:
6.2.5 / 20 ...数组类型描述了具有特定成员对象类型的连续分配的非空对象集,称为元素类型。
但是在WG21 / N4527中,即在C ++中,相应的句子变为
8.3.4 / 1 ...数组类型的对象包含一个连续分配的非空N个子类型的T类型。
而“describe”一词改为“contains”,这不能保证数组的地址等于第一个元素的地址。这种改变是故意的还是无意的?如果是故意的,那么数组的地址是否等于C ++中第一个元素的地址?如果确实如此,C ++标准中的哪一段可以保证这一点?
答案 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
标准保证p1
和p2
指向同一地址。
答案 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()
}