首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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-限定。

二次

代码语言:javascript
复制
// 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 = {};

二次

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

二次

代码语言:javascript
复制
int* p = new int[0]; // accessing p[0] or *p is undefined
delete[] p; // cleanup still required

二次

赋值

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

二次

代码语言:javascript
复制
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:它构造指向数组的第一个元素的指针。每当数组出现在不需要数组的上下文中时,都会使用这种转换,但是指针是:

二次

代码语言:javascript
复制
#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
}

二次

多维阵列

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

二次

代码语言:javascript
复制
// 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:数组到指针衰减的指针只应用一次。

二次

代码语言:javascript
复制
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的未知界数组”,这是一种不完全类型,除非在声明中使用聚合初始化器*

二次

代码语言:javascript
复制
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"

二次

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

二次

代码语言:javascript
复制
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编程语言中,指向未知界数组的指针与指向已知界数组的指针兼容,因此在两个方向上都是可转换和可分配的。

二次

代码语言:javascript
复制
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引用的另一个强制转换或函数调用。

二次

代码语言:javascript
复制
#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
 
}

二次

产出:

二次

代码语言:javascript
复制
24
24
24
24
24

二次

代码语言:txt
复制
 ? cppreference.com

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

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com