在线文档教程
C++
语言 | Language

Array declaration

数组声明

声明数组类型的对象。

句法

数组声明是指其报关员有表格。

noptr-declarator expr(optional) attr(optional)(1)

noptr-declarator-any valid declarator, but if it begins with *, &, or &&, it has to be surrounded by parentheses.
attr(C++11)-optional list of attributes
expr-an integral constant expression (until C++14)a converted constant expression of type std::size_t (since C++14), which evaluates to a value greater than zero

表格的声明T a[N];,声明a的数组对象。N连续分配的类型对象T数组的元素被编号。0, …, N - 1,并且可以使用下标算子。[],如a[0]...,a[N - 1]...

数组可以从任意基本类型%28除外void%29,指针,,,对成员的指示,,,班,,,枚举,或者来自其他数组%28,在这种情况下,该数组被称为多维%29。没有引用数组、函数数组或抽象类类型数组。

应用简历-资格对于数组类型%28,通过类型类型为%28或模板类型,操纵%29将限定符应用于元素类型,但任何元素为cv限定类型的数组类型都被认为具有相同的cv-限定。

二次

// a and b have the same const-qualified type "array of 5 const char" typedef const char CC; CC a[5] = {}; typedef char CA[5]; const CA b = {};

二次

当与新。[]---表达,数组的大小可能为零;这样的数组没有元素:

二次

int* p = new int[0]; // accessing p[0] or *p is undefined delete[] p; // cleanup still required

二次

赋值

数组类型的对象不能作为一个整体进行修改:即使它们是lvalue%28等。数组的地址可以取为%29,它们不能出现在赋值运算符的左侧:

二次

int a[3] = {1, 2, 3}, b[3] = {4, 5, 6}; int (*p)[3] = &a; // okay: address of a can be taken a = b; // error: a is an array struct { int c[3]; } s1, s2 = {3, 4, 5}; s1 = s2; // okay: implicity-defined copy assignment operator // can assign data members of array type

二次

数组对指针衰减

有一个隐式转换从数组类型的lvalue和rvalue到指针类型的rvalue:它构造指向数组的第一个元素的指针。每当数组出现在不需要数组的上下文中时,都会使用这种转换,但是指针是:

二次

#include <iostream> #include <numeric> #include <iterator> void g(int (&a)[3]) { std::cout << a[0] << '\n'; } void f(int* p) { std::cout << *p << '\n'; } int main() { int a[3] = {1, 2, 3}; int* p = a; std::cout << sizeof a << '\n' // prints size of array << sizeof p << '\n'; // prints size of a pointer // where arrays are acceptable, but pointers aren't, only arrays may be used g(a // okay: function takes an array by reference // g(p // error for(int n: a) // okay: arrays can be used in range-for loops std::cout << n << ' '; // prints elements of the array // for(int n: p) // error // std::cout << n << ' '; std::iota(std::begin(a), std::end(a), 7 // okay: begin and end take arrays // std::iota(std::begin(p), std::end(p), 7 // error // where pointers are acceptable, but arrays aren't, both may be used: f(a // okay: function takes a pointer f(p // okay: function takes a pointer std::cout << *a << '\n' // prints the first element << *p << '\n' // same << *(a + 1) << ' ' << a[1] << '\n' // prints the second element << *(p + 1) << ' ' << p[1] << '\n'; // same }

二次

多维阵列

当数组的元素类型是另一个数组时,就会说该数组是多维的:

二次

// array of 2 arrays of 3 int each int a[2][3] = {{1, 2, 3}, // can be viewed as a 2 × 3 matrix {4, 5, 6}}; // with row-major layout

二次

注意,当应用数组到指针衰减时,多维数组被转换为指向其第一个元素%28e的指针。指向其第一行或其第一个平面%29:数组到指针衰减的指针只应用一次。

二次

int a[2]; // array of 2 int int* p1 = a; // a decays to a pointer to the first element of a int b[2][3]; // array of 2 arrays of 3 int // int** p2 = b; // error: b does not decay to int** int (*p2)[3] = b; // b decays to a pointer to the first 3-element row of b int c[2][3][4]; // array of 2 arrays of 3 arrays of 4 int // int*** p3 = c; // error: c does not decay to int*** int (*p3)[3][4] = c; // c decays to a pointer to the first 3 × 4-element plane of c

二次

未知界数组

如果在数组的声明中省略Exr,则声明的类型是“T的未知界数组”,这是一种不完全类型,除非在声明中使用聚合初始化器*

二次

extern int x[]; // the type of x is "array of unknown bound of int" int a[] = {1, 2, 3}; // the type of a is "array of 3 int"

二次

由于数组元素不能具有不完全类型,因此多维数组不能在第一个维度中具有未知的绑定:

二次

extern int a[][2]; // okay: array of unknown bound of arrays of 2 int extern int b[2][]; // error: array has incomplete element type

二次

可以形成对未知绑定数组的引用和指针,但不能从数组和已知绑定数组中初始化或分配指针。注意,在C编程语言中,指向未知界数组的指针与指向已知界数组的指针兼容,因此在两个方向上都是可转换和可分配的。

二次

extern int a1[]; int (&r1)[] = a1; // okay int (*p1)[] = &a1; // okay int (*q)[2] = &a1; // error (but okay in C) int a2[] = {1, 2, 3}; int (&r2)[] = a2; // error int (*p2)[] = &a2; // error (but okay in C)

二次

指向未知绑定数组的指针不能参与指针算法控件的左边不能使用。下标算子,但可以取消引用。中不能使用指针和对未知绑定数组的引用。功能参数%28,直到C++14%29。

数组r值

虽然数组不能按值从函数返回,也不能成为大多数强制转换表达式的目标,但数组prvalue可以通过使用类型别名来构造数组临时使用支撑-初始化功能铸造...

Like class prvalues, array prvalues convert to xvalues by temporary materialization when evaluated.(since C++17)

列阵x值可以通过访问类rvalue的数组成员或使用std::move或者返回rvalue引用的另一个强制转换或函数调用。

二次

#include <iostream> #include <type_traits> #include <utility> void f(int (&&x)[2][3]) { std::cout << sizeof x << '\n'; } struct X { int i[2][3]; } x; template<typename T> using identity = T; int main() { std::cout << sizeof X().i << '\n'; // size of the array f(X().i // okay: binds to xvalue // f(x.i // error: cannot bind to lvalue int a[2][3]; f(std::move(a) // okay: binds to xvalue using arr_t = int[2][3]; f(arr_t{} // okay: binds to prvalue f(identity<int[][3]>{{1, 2, 3}, {4, 5, 6}} // okay: binds to prvalue }

二次

产出:

二次

24 24 24 24 24

二次

© cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

http://en.cppreference.com/w/cpp/language/Array