數組

與vector的異同

  • 相同:都是存放類型相同對象的容器
  • 不同:數組的大小確定不變,不能隨意向數組中增加元素

1、定義和初始化內置數組

  數組中元素的個數也屬於數組類型的一部分,編譯的時候維度應該是已知的,也就是說,維度必須是一個常量表達式。

  默認情況下,數組的元素被默認初始化。

NOTE:

  • 定義數組的時候必須制定數組類型,不允許用auto
  • 數組元素應爲對象,不能是引用

顯式初始化數組元素

  可以對數組元素進行列表初始化,此時允許忽略數組的維度。當指定了維度,則維度應比列表初始值的數量多,當維度比初始化列表的數量大時,多的部分默認初始化。

字符數組的特殊性

  字符數組允許用字符串字面值來進行初始化,但數組的維度必須比字符串字面值大1,用來盛放添加的空字符'/0';

char a[]="hi";
char a1[2]="hi";    //錯誤,最後的空字符'/0'沒地方放

不允許拷貝和賦值

  不能將數組的內容拷貝給其他數組作爲初始值,也不能用數組爲其他數組賦值

int a[]={0,1,2};
int b[]=a;     //不允許使用一個數組初始化另一個數組       
int b=a;        //不允許把數組直接賦值給另一數組

理解複雜的數組聲明

  數組本身也是對象,因此可以定義指向數組的指針和引用。

1

2

3

4

int *ptrs[10];    //含有10個整型指針的數組

int &refs[10]=a;    //錯誤,不存在引用的數組,數組的元素必須是對象

int (*Parray)[10]=&arr;    //Parray指向一個含有10個整數的數組

int (&arrRef)[10]=arr;    //arrRef引用一個含有10個整數的數組

2、訪問數組元素

  可以使用範圍for語句或下標來訪問數組元素

  在使用下標的時候,通常將其定義爲size_t類型。size_t類型是一種機器相關的無符號類型,它被設計得足夠大以便能表示內存中任意對象的大小。在cstddef頭文件中定義了size_t類型。

  遍歷數組所有元素,最好的方法是範圍for語句。

檢查下標的值

3、指針和數組

  在很多用到數組名字的地方,編譯器都會自動地將其替換爲一個指向數組首元素的指針。

  對數組的元素使用取地址符就能得到指向該元素的指針。

指針也是迭代器

  指向數組元素的指針可以執行迭代器一樣的操作。

複製代碼

    int a[10] = { 0 };
    int n = 0;
    for (auto &i : a)
    {
        i = n;
        n++;
    }
    int *p1 = a;    //相當於迭代器的begin
    int *p2 = &a[10];    //相當於迭代器的end
    for (int *p3 = p1; p3 != p2; p3++)
    {
        cout << *p3 << endl;
    }

複製代碼

標準庫函數begin和end

  上述使用a[10]的地址來表示尾後指針很容易出錯,因此標準庫定義了數組用的begin和end函數來得到數組的首指針和尾後指針,其在iterator頭文件中。

複製代碼

int a[10] = { 0 };
    int n = 0;
    for (auto &i : a)
    {
        i = n;
        n++;
    }
    /*int *p1 = a;    
    int *p2 = &a[10];*/
    int *p1 = begin(a);
    int *p2 = end(a);
    for (int *p3 = p1; p3 != p2; p3++)
    {
        cout << *p3 << endl;
    }

複製代碼

二者同樣的效果。

指針運算

  給指針加上一個整數,得到的新指針仍需指向同一數組的其他元素,或者指向同一數組的尾元素的下一位置。

解引用和指針運算的交互

  指針加上一個整數得到的結果仍是一個指針,因此可以解引用該指針。

下標和指針

  對數組執行下標運算其實是對指向數組元素的指針執行下標運算。

int i=a[2];
//上面的下標引用其實是下面的過程
int *p=a;
i=*(p+2);

  雖然標準庫類型vector和string也能執行下標運算,但是數組與它們相比還是有所不同。標準庫類型限定使用的下標必須是無符號類型,而內置的下標運算無此要求。

int *p=&a[2];
int j=p[1];    //實際是a[3]
int k=p[-2];    //實際上是a[0]

與舊代碼的接口

混用string對象和C風格字符串

  C風格字符串:以空字符結尾的字符數組。

  string提供一個名爲c_str()的成員函數來將string轉換爲C風格字符串,返回的是const char*類型。

使用數組初始化vector對象

   指明要拷貝區域的首元素地址和尾後地址即可。

int a[]={0,1,2,3,4,5};
vector<int> v(begin(a),end(a));

NOTE:不能用vector初始化數組。

  • 儘量不使用數組和指針,而使用vector和迭代器
  • 儘量不使用C風格字符串,而使用string

多維數組

  C++語言中沒有多維數組,通常所說的多維數組其實是數組的數組。

int a[3][4];  //大小爲3的數組,每個元素是含有4個整數的數組

int b[10][20][30];

多維數組的初始化

  使用花括號括起來的一組值初始化多維數組,和普通數組初始化一樣,只是數組的元素也是數組而已。

複製代碼

int a[3][4]={
{0,1,2,3},
{4,5,6,7},
{8,9,10,11}};

int a[3][4]={0,,1,2,3,4,5,6,7,8,9,10,11};    //和上面的效果一樣

int a[3][4]={{0},{1},{3}};    //其餘的默認初始化

複製代碼

多維數組的下標引用

  表達式含有的下標運算符數量和數組的維度一樣多,該表達式的結果將是給定類型的元素;當比數組的 維度數量小時,表示的是內層數組。

使用範圍for語句處理多維數組

複製代碼

size_t cnt=0;
for(auto &row:a)
   for(auto &col:row)
        col=cnt;
        cnt++;
}

複製代碼

NOTE:

  使用範圍for語句處理多維數組,除了最內層的循環外,其他所有循環的控制變量都應用是引用類型。爲了防止編譯器將auto控制變量轉換成數組首元素的指針。

指針和多維數組

  當程序使用多維數組的名字時,也會自動將其轉換成指向數組首元素的指針。

  也可以通過使用auto或decltype來遍歷多維數組

複製代碼

    int a[3][4] = {};
    int cnt = 0;
    for (auto p = a; p != a + 3; p++)
    {
        for (auto q = *p; q != *p + 4; q++)
        {
            *q = cnt;
            cnt++;
        }
    }
    for (auto p = a; p != a + 3; p++)
    {
        for (auto q = *p; q != *p + 4; q++)
        {
            cout << *q << " | ";
        }
        cout << endl;
    }    

複製代碼

也可以使用begin和end來簡化

複製代碼

        int a[3][4] = {};
    int cnt = 0;
    for (auto p = begin(a); p != end(a); p++)
    {
        for (auto q = begin(*p); q != end(*p); q++)
        {
            *q = cnt;
            cnt++;
        }
    }
    for (auto p = begin(a); p != end(a); p++)
    {
        for (auto q = begin(*p); q != end(*p); q++)
        {
            cout << *q << " | ";
        }
        cout << endl;
    }

複製代碼

類型別名簡化多維數組的指針

複製代碼

    using int_array=int[4];
    int a[3][4] = {};
    int cnt = 0;

    for (auto p = begin(a); p != end(a); p++)
    {
        for (auto q = begin(*p); q != end(*p); q++)
        {
            *q = cnt;
            cnt++;
        }
    }
    for (int_array *p = a; p != a + 3; p++)
    {
        for (int *q = *p; q != *p + 4; ++q)
        {
            cout << *q << " | ";
        }
        cout << endl;
    }    

複製代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章