chapter3.pdf

数组

数组的引入I

声明

int a //类型:int
int b[10] //类型:int[10]
int b[x]; //error:可变长度数组,variable length array c, c语音支持但是c++不支持
C++数组类型标准:const exp
1.常量,
2.在编译期可以确定
3.可转为size_t,且大于零 //error: int b[3.14]; int b[-1]; int b[0]

初始化

缺省初始化: int b[3];//函数中缺省初始化为随机值,全局域内初始化为0
聚合初始化:

  • int b[3] = {1,2,3};
  • int b[3] = {1,2}//其中b[2] = 0
  • int b[3] = {}; //元素初始化为0
  • int b[] = {1,2,3}//自动推导b的类型为 int[3]
  • int b[]; //ERROR:需要给出值
  • int b[2] ={1,2,3} //ERROR:初始化元素个数要小于类型

注意:

  • 不能用auto声明数组:auto b = {1,2,3}; //类型不为int[3]
  • 数组不支持复制,数组做右值退化为指针
    • int b[] = {1,2,3}; int a[3] = b //ERROR
    • int b[] = {1,2,3}; auto a = b // a的类型为int*
    • int b[] = {1,2,3}; auto& a = b // a的类型为int(&)[3]
  • 字符串数组具有特殊性

    • char str[] = “Hello” //类型为char[6],默认加了’\0’
    • char str[] = {‘H’,’e’,’l’,’l’,’o’},//类型为char[5]

      数组的引入II

      数组的复杂类型:

      指针的数组
      int a[3]; //a为有三个指针的数组,类型int[3]
      int a[3] = {&x,&y,&z};
      数组的指针
      int (
      a)[3] = &b; //其中int b[3], a是一个指针,指向int[3]。
      数组的引用
      int (&a)[3] = b; //数组的引用,其中int b[3]
      引用的数组//ERROR,引用只是别名

      数组中的元素访问

      数组元素为左值,作为右值使用时退化为int*
  • int a[3] = {1,2,3}; auto b = a // b为int*

  • a[0]系统先翻译为int*
  • 指针也可以使用中括号,如 int* ptr = &x, 则ptr[1] = 2;
    • 注意溢出

      []中括号的解释:ptr[n]//对于系统的内建类型,[] = *(ptr + n) 等价与 n[ptr] == ptr[n]

从数组到指针

  • 大多数情况会产出数组到指针的隐式转换,除了sizeof,de
  • 隐式转换后丢失了数组大小信息,编译器无法进行越界检查
  • 可以通过声明引用来避免隐式转换int a[3]; int& b = a; //b 为int(&)[3]

image.png上:内存地址,下:保存的值

  • 不要用extern指针声明数组
    • extern int array[4] //声明连接到其他文件中的定义
    • extern int* array; array = [1,2,3] //ERROR,array[0]表示0x20000001地址中的值,该地址不一定存在

image.png

  1. - 可以改为extern int array[]; 不确定数组个数时可以这么声明。//不完整类型
  • begin,end
    • int a[4];
    • std::begin(a),std::end(a),//可写
    • std::cbegin(a),std::cend(a),//只读
    • 不完整类型和auto降级无法使用上述函数
  • 指针算数:
    • 增加,减少,1~n
    • 比较: ==, !=, >=, <=, >, < //建议只用于同一个数组的指针
    • 求距离:两个指针相减,//两个指针之间包含的元素个数
    • 解引用
    • 指针索引

多维数组

类型

int x2[3][4];//x2[0]为int(&)[4]类型

聚合初始化

一层大括号 && 多层大括号
建议多层大括号初始化

  • int x3[3][4] = {{1,2,3,4}{5,6,7}};
  • int x3[][] = {{1,2,3,4}{5,6,7,8}};//错误:只能省略最高位数组个数

    • int x3[][4]

      索引与遍历

      1. for(auto& p:x3){
      2. //需要加&,否则p为指针
      3. for(auto q:p){
      4. }
      5. }
  • 按照低位遍历可以减少开销

    • int x2[2][4];//按照x2[0][0~3],x2[1][0~3]遍历

      image.pngvector

      初始化

  • 缺省初始化:则为0个元素

  • 聚合初始化:
    • vector x = {1,2,3};//大括号内为初始化列表
    • vector x(3,1); //包含3个1