在C++中,数组名是否是常量指针?

18

我对数组名a有一个问题

int a[10]

C++中数组名是如何定义的?它是一个常量指针吗?它是这样定义的还是我们可以这样看待它?在数组名上可以执行哪些操作?

2个回答

34

C++标准定义了数组及其行为。请查看索引。它不是指针,也不管它是否是const,它不是其他任何东西,它就是一个数组。

为了看到区别:

int a[10];
int *const b = a;

std::cout << sizeof(a); // prints "40" on my machine.
std::cout << sizeof(b); // prints "4" on my machine.

很明显,a和b不是相同的类型,因为它们具有不同的大小。

在大多数情况下,数组名“退化”为指向其自身第一个元素的指针。你可以把它想象成自动转换。结果是一个rvalue,这意味着它是“只是”一个指针值,并且不能被赋值,类似于函数名退化为函数指针时的情况。这并不意味着它是“const”,但它是不可赋值的。

所以,一个数组“就像”一个指针,就像一个函数“就像”一个函数指针,或者一个长整型“就像”一个整型一样。也就是说,它实际上并不是,但是由于转换,你可以在大多数情况下将其用作一个指针。


a将打印数组中第一个元素的值,因此应该指向数组中第一个元素的内存地址。那么为什么sizeof运算符会给出数组a所有元素的大小,而不是只给出存储数组第一个元素内存地址的大小? - user1825567
1
因为表达式*a中有一个隐式转换(称为“衰减”),从数组类型到指针类型。你可以把它看作是*pointer_to_first_element_of(a)的简写。这时,sizeof(a)sizeof(pointer_to_first_element_of(a))不必相同,应该很明显了。a不是一个指针。任何告诉你它是指针的人要么不懂C,要么不尊重你的能力以理解C。 - Steve Jessop

6
一个数组名不是一个常量指针 - 但是在许多情况下它的行为就像一个常量指针(基本上一看就转换为一个),所以对于大多数目的来说,它都是这样。根据6.3.2.1/3 "Other operands/Lvalues, arrays,and function designators"的规定,在以下情况下,一个具有"类型为数组的类型"的表达式被转换为具有指向数组对象初始元素的"type为指向类型的指针"的表达式,并且不是一个lvalue:当它是sizeof操作符或一元&操作符的操作数,或者是用于初始化数组的字符串文字。

5
我需要指出这是C标准的引用。在C++中,数组不会退化。它会考虑上下文,例如:int a[10]; int(&r)[10] = a; /*没有退化*/; - Johannes Schaub - litb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接