字符串和數組


此處的數組非順序容器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; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM