发表于: 2019-01-06 20:11:25

1 722



今天完成的事情:

1、今天完成了小课堂的制作及讲解,并上传了讲解视频。

1、学习了js有关字符串的相关知识。


明天计划的事情:

1、明天计划完成js任务一。


收获:


字符串和数组

此处的数组非顺序容器array

初始化,

使用下标访问数组时,下标定义为size_t类型。

beg 和 end 函数(注意和 顺序容器中的 beg end成员的区别)

int a[10];

int *beg = beg(a);

int *end = end(a); // 返回末尾元素的后一个位置

 

 多维数组:

  本质:数组的数组。常把第一维叫 行,第二维度叫 列。

  初始化:用一个花括号初始化(全部的值放一起,逗号隔开,个数 <= 行 * 列,举例:int ia[3][4]= {1, 2, 3, 4 },显式初始化了第一行,剩下的被初始化为0),或者用多个花括号初始化(同样最外层的大括号少不了,但是里层就是一个大括号表示一行的初始化,举例:int ia[3][4]= { {1}, { 2}, {3} },显式初始化了每一行的第一个元素,剩下的被初始化为0)

  对多维数组进行处理的三种方式:下标、范围for 和 指针

  a. 下标:

constexpr size_t row = 3, col=4;int ia[ row ][ col ] ; // 二维数组未被初始化for (size_t i = 0; i != row; i++) // 对每一行  for (size_t j = 0; j != col; j++) // 对行内每一列    ia [ i ][ j ] = i * col + j;

  b. 范围 for 

复制代码
constexpr size_t row = 3, col=4;int ia[ row ][ col ] ; // 二维数组未被初始化for (auto &r : ia) // 对每一行,即外层数组的每一个元素  for (auto &c : r ) {// 对行内每一列,即内层数组的每一个元素     c = cnt;
       cnt++;  
  }  
复制代码

  预备:程序使用数组名时,会自动将其转换成指向数组首个元素的指针。

  第一个 for 遍历 ia 的每一个元素,这些元素是大小为4的数组,所以r 的类型为含有4个元素的引用。

  第二个 for 遍历 r 的每一个元素,这些元素类型为整形,所以 c 的类型为整形的引用。

  即使第二个for 循环里不对数组的元素进行写操作,不改变他们的值,第一个for循环 r 也要用引用的形式?为什么:

    因为第一个for循环遍历 ia 的每一个元素,这些元素是大小为4 的数组,若 r 不是引用,编译器初始化 r 时会将这些数组形式的元素(像其他类型的数组一样)自动转换成指向这些数组内首元素的指针,这样得到的 r 的类型就是 int*,这样第二层循环编译器试图在一个int* 内遍历,这显然是不对的,

  所以:要使用范围for 语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是 引用 类型。 -- 《C++ primer》

  c. 指针和多维数组  

复制代码
// 读取二维数组 ia [ 3 ][ 4 ]中的每个值
 for ( auto p = ia;  p != ia + 3; ++p){     for (auto q = *p; q != *p + 4; ++p)    
        cout << *q << ' '; 
     cout << endl;    
}    
复制代码

 

   预备:

    int ia [ 3 ][ 4 ];

    int (*p)[4] = ia; // ia 被转换为指向 ia 内三个 数组 元素的首地址,按照《C++ primer》的说法,从内往外的顺序来理解这个表达式

          // (*p) 表示p 是个指针,再看右边,  可知p 是指向大小为 4 的数组的指针,再看右边,这个数组的元素的类型为 int ,这样就可以知道 p 指向含有四个整数的数组。

          // 

    int *p[4];   // p 是整形指针的数组

  有了这个基础就可以解释上面的代码了。C11的新标准,可以使用auto就能尽可能的避免在数组前面加上一个指针类型了,

  即:auto p = ia(和 int (*p)[4] = ia;是一样的);auto q = *p; p 是指向一个含有4个整数的数组,那么*p 就是一个含有4元素的数组,所以*p被自动地转换成指向该数组首元素的指针,这就解释了为什么 内层for 循环 的判别条件为 q != *p + 4;

 附:《C++primer》习题 3-43

  三种不同版本输出二维数组的元素(不能使用 类型别名 或 auto 或 decltype):  

复制代码
  
   // 范围 for    cout<< "range for :" <<endl;    for(const int (&row)[4] : ia) {        for(int col : row)            cout << col << " ";        cout << endl;    }    // 普通for,使用下标    cout<< "普通for,使用下标" <<endl;    for(size_t i = 0; i != 3; ++i) {        for(size_t j = 0; j!= 4; ++j)            cout << ia[i][j]<< " ";        cout <<endl;    }    // 普通for,使用指针    cout << " 普通for,使用指针 " <<endl;    for(int(*row)[4] = ia; row != ia + 3; ++row) {        for(int *col = *row; col != *row +4; ++col)            cout << *col<<" ";        cout << endl;    }
复制代码

    使用类型别名替代循环控制变量的类型:

复制代码
   using int_array = int[4];    // 范围 for
    cout<< "range for :" <<endl;    for(int_array&row  : ia) {        for(int col : row)
            cout << col << " ";
        cout << endl;
    }    // 普通for,使用下标
    cout<< "普通for,使用下标" <<endl;    for(size_t i = 0; i != 3; ++i) {        for(size_t j = 0; j!= 4; ++j)
            cout << ia[i][j]<< " ";
        cout <<endl;
    }    // 普通for,使用指针
    cout << " 普通for,使用指针 " <<endl;    for( int_array *row  = ia; row != ia + 3; ++row) {        for(int *col = *row; col != *row +4; ++col)
            cout << *col<<" ";
        cout << endl;
    }
复制代码

  使用类型别名:

复制代码
    // 范围 for
    cout<< "range for :" <<endl;    for(auto &row  : ia) {        for(int col : row)
            cout << col << " ";
        cout << endl;
    }    // 普通for,使用下标
    cout<< "普通for,使用下标" <<endl;    for(size_t i = 0; i != 3; ++i) {        for(size_t j = 0; j!= 4; ++j)
            cout << ia[i][j]<< " ";
        cout <<endl;
    }    // 普通for,使用指针
    cout << " 普通for,使用指针 " <<endl;    for( auto *row  = ia; row != ia + 3; ++row) {        for(int *col = *row; col != *row +4; ++col)
            cout << *col<<" ";
        cout << endl;
    }



返回列表 返回列表
评论

    分享到