C++中的数组索引类型

24

C++编程语言中的数组索引类型是什么?例如,在以下语句中:

int tab[5];

数字5会被转换成什么类型?还是只是普通的整型(int)?


10
我只是好奇这些信息对你有什么用处。 - cnicutar
20
他也许也很好奇? - Anthony
1
关于C语言数组访问的相关内容:https://dev59.com/x3A75IYBdhLWcg3wqK7_ - Ciro Santilli OurBigBook.com
1
如果有一个类似于std::size_t的std::index_t会很不错。 - feedc0de
@feedc0de 有 gsl::index,它有很大的机会加入标准库 https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Res-subscripts - diapir
4个回答

16
在这段代码中,5 是一个普通的整数字面值,因此它在这里只是一个普通的 int
n3290(~C++11)的§8.3.4 数组指定了数组声明符:

In a declaration T D where D has the form

D1 [ constant-expressionopt ] attribute-specifier-seqopt

and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is an array type; if the type of the identifier of D contains the auto type-specifier, the program is ill-formed. T is called the array element type; this type shall not be a reference type, the (possibly cv-qualified) type void, a function type or an abstract class type. If the constant-expression (5.19) is present,it shall be an integral constant expression and its value shall be greater than zero.

§5.2.1 子脚本 描述了方括号中可以用于表达式的内容:

后缀表达式加上一个方括号内的表达式仍为后缀表达式。这两个表达式中的一个应该是“指向 T 的指针”,另一个应该是无作用域枚举类型或整数类型。结果为类型为“T”的左值。类型“T”应该是完全定义的对象类型。 表达式 E1[E2] 等同于 *((E1)+(E2))(根据定义)。


错误的章节。他问的是关于声明,而你引用了下标表达式的描述。这是不同的,因为在他的情况下,不允许有负整数值。因此,是否适用相同的约束条件并不明显。 - Johannes Schaub - litb
@JohannesSchaub-litb:添加了声明符的相关部分。我认为问题并不特别涉及声明部分,这就是为什么我将下标操作部分作为参考放置的原因。 - Mat
@Johannes Schaub - litb:公平地说,标题是C++的数组索引类型。我在我的答案中已经涵盖了数组声明部分。 - jfs

5
这个问题有点混淆。标题提到了“数组索引类型”,但在问题中,您似乎询问其他内容。您是在询问数组的“大小”还是“索引”?一个“声明”的数组的大小必须大于零; 它可以是任何整数类型:int,char,signed char,unsigned int等。在您的问题中,字面值5的类型是int。
然而,如果您正在问有关数组索引类型的问题,则它必须是整数类型之一。数组的索引类型也可以是int,因为它甚至可以是负数。
int a[10][10];

int x = a[3][-1]; //same as a[2][9]
int y = a[3][-2]; //same as a[2][8]
int z = a[3][-3]; //same as a[2][7]

1
C++11标准(草案N3242)§8.3.4规定该值应大于零。 - jfs
2
@J.F.Sebastian:如果这个值“必须大于零”,那么写a[0][0]是非法的吗?我认为你把“数组的索引”和“数组的大小”混淆了。必须保证的是“大小”大于零! - Nawaz
2
数组的大小必须大于零- 这并不完全正确。只有对已声明的数组才是正确的。例如,这样是可以的:new int [0]. - Johannes Schaub - litb
@Nawaz:问题中的代码正如你所注意到的,是一个数组声明。我以为你指的是可能的值,而不是5。你说得对,我混淆了数组的索引和大小。 - jfs
@JohannesSchaub-litb:我同意这一点。但是问题提到了声明的数组,所以我只回答了那部分。更详细的答案可能包括,如果它是用户定义类并重载了 operator[],则类型可以是任何东西。 - Nawaz

5

int tab[5];是一个数组声明。

数组声明接受一个大于零的整型常量表达式(C++11:§8.3.4)。

§5.19.4 (n3242):

如果常量表达式是整型或枚举类型,则它是整型常量表达式。【注:这样的表达式可用作数组边界(8.3.4,5.3.4),case表达式(6.4.2),位域长度(9.6),...】


5是一个整型字面值(§2.14.2)。它的类型是int

§2.14.2 (n3242)

2 整数字面值的类型是表6中相应列表中的第一个,其中其值可以表示。

3 如果一个整数字面值不能被其列表中的任何类型表示,并且扩展整数类型(3.9.1)可以表示其值,则它可以具有该扩展整数类型。...

表6中没有后缀的十进制常量的类型为:intlong intlong long int


3

如果你想使用不同的类型,请在后面加上相应的标识符,比如:

int代表整数。

5         // int
5u        // unsigned int
5l        // long
5ul       // unsigned long 

1
注意:没有后缀的整数字面值可以是 intlong intlong long int 或者可能有扩展的整数类型。参见我的回答例如,5000000000 在我的机器上是 long 类型,在 ideone.com 上是 long long 类型。 - jfs

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