RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C++入門之數(shù)組的概念

jf_78858299 ? 來源:QStack ? 作者: 月下西樓 ? 2023-03-17 14:14 ? 次閱讀

背景

上一篇文章我們介紹了C++中的迭代器,這篇文章將會介紹C++中數(shù)組的概念,數(shù)組是一種和vector類似的數(shù)據(jù)結(jié)構(gòu),但是其在性能和靈活性上的權(quán)衡中選擇了性能而放棄了一定的靈活性,其與vector相同的地方是,它們都是同一類型的對象的容器,也都可以通過下標訪問。其不同點是數(shù)組的大小是固定的,所以無法向一個數(shù)組添加元素,也正是因為其大小固定,所以其在運行時有更好的性能。

定義和初始化數(shù)組

數(shù)組是一個復合類型,可以通過類似a[d]的形式定義,其中a是數(shù)組名,d是數(shù)組的容量,d必須要大于0,數(shù)組的容量是數(shù)組類型的一部分,其導致數(shù)組容量必須要在編譯時就已知,這要求數(shù)組容量必須是常量表達式,以下提供了數(shù)組聲明的幾種形式:

unsigned cnt = 42; //不是一個常量表達式
constexpr unsigned sz = 42; //是常量表達式

int arr[10]; //聲明一個容量為10的整型數(shù)組
int *parr[sz]; //42個指向整形指針的數(shù)組
string bad[cnt]; //這是個錯誤聲明,因為cnt不是常量表達式

默認情況下,數(shù)組里面的元素都會被默認初始化。

我們可以通過列表初始化一個數(shù)組,通過這種方式我們在定義時可以忽略數(shù)組的容量,如果我們指定了數(shù)組容量,那么在列表初始化時初始化的元素數(shù)量不能超過設(shè)置的容量值,如果少于設(shè)置的數(shù)組的數(shù)量,沒有指定值的元素會使用默認初始化的值,例子如下:

const unsigned sz = 3;
int a1[sz] = {0, 1, 2};
int a2[] = {0, 1, 2}; //可以忽略數(shù)組的容量
int a3[5] = {0, 1, 2}; //等價于{0, 1, 2, 0, 0}
string a4[3] = {"hi", "bye"}; //等價于{"hi", "bye", ""}
int a5[2] = {0, 1, 2}; //錯誤

字符數(shù)組的定義

字符數(shù)組有一個額外的初始化方式,就是可以通過一個字符還去初始化字符數(shù)組,但是需要注意的是string是以null字符結(jié)尾的,所以在定義數(shù)組容量時要考慮null字符:

char a1[] = "C++"; //其等價于{'C', '+', '+', '\\0'}
char a2[6] = "Daniel" //錯誤,其未考慮到null字符

?需要注意的是一些編譯器是不支持數(shù)組的拷貝,如果直接通過一個數(shù)組去初始化另一個數(shù)組可能會報錯

?

理解復雜的數(shù)組聲明

正如vector,array也可以容納所有的類型,例如指針的數(shù)組,由于數(shù)組是一個對象,所以可以定義指向數(shù)組的指針和引用,,定義指向數(shù)組的指針或者引用可以通過以下方式:

int *ptre[10]; //ptre是一個數(shù)組,其中的元素是10個指向整型的指針
int (*parray)[10] = &arr; //parray是一個指針,其指向的對象是一個容量為10的整型數(shù)組
int (&arrRef)[10] = arr; //arrRef是一個引用,其指向的是一個容量為10的整型數(shù)組

?在理解聲明時可以按照從左到右,從內(nèi)到外的順序。

?

指針與數(shù)組

在C++中指針和數(shù)組關(guān)系是很近的,一般來說,當我們使用一個數(shù)組,編譯器會自動將其轉(zhuǎn)化為一個指針,一般來說我們是通過地址操作符來獲取一個對象的指針的,但是對于數(shù)組而言,當我們使用數(shù)組時,編譯器將會自動獲取一個指針指向數(shù)組的第一個元素:

string nums = {"one", "two", three}; 
string *p = &nums[0]; //p指向nums的第一個元素
string *p2 = nums //等價于string *p = &nums[0];

?在大多數(shù)表達式中,我們使用數(shù)組對象,我們其實是獲取一個指針指向數(shù)組的第一個元素

?

由于這個影響,我們對于數(shù)組的操作其實絕大多數(shù)都是對于指針的操作,其中一個比較明顯的是當我們使用auto和數(shù)組去初始化一個變量時,其實是聲明了一個指針而不是數(shù)組:

int ia[] = {0, 1, 2, 3, 4};
auto ia2(ia); //ia2是一個整形指針,指向ia的第一個元素
ia2 = 43 //錯誤,不可以將int賦值給一個指針
auto ia3(&ia[0]) //這樣看起來更清楚,ia3是整型指針

需要注意的是當我們使用之前提到的decltype時不會發(fā)生這種轉(zhuǎn)化, decltype(ia)返回的類型是10個整型的數(shù)組:

decltype(ia) ia3 = {0, 1, 2, 3, 4};
ia3 = p; // 錯誤,不可以將一個整型指針賦值給一個數(shù)組
ia3[4] = i; //正確,可以對數(shù)組的元素賦值

指針是迭代器

指針也是迭代器,指向數(shù)組元素的指針同樣支持我們之前提到的vector和string中迭代器的操作,例如可以通過自增操作實現(xiàn)從一個元素移動到下一個元素:

int arr[] = [0, 1, 2, 3, 4, 5];
int *p = arr; //現(xiàn)在p指向arr[0]
++p; //現(xiàn)在p指向arr[1]

正如我們可以使用迭代器遍歷vector中的元素,我們也可以使用指針去遍歷數(shù)組中的元素,我們可以通過上面的方式獲取數(shù)組的第一個元素的指針,那么我們又該如何獲取數(shù)組最后一個元素之后的不存在的元素呢,我們可以通過以下方式:

int *e = &arr[6];

我們只可以獲取最后一個元素的下一個元素的地址

for (int *b = arr; b != e; ++b)
    cout<< *b<

雖然我們可以通過上述方式獲取數(shù)組的第一個元素的地址和最后一個元素的下一個地址,但是這并不是一個好的方法,在新的規(guī)范中已經(jīng)提供了新的函數(shù)begin和end可以獲取數(shù)組的第一個元素的地址和最后一個元素的下一個地址:

int ia[] = {0, 1, 2, 3, 4};
int *beg = begin(ia);
int *last = end(ia);

指針的算術(shù)運算

指向數(shù)組元素的指針可以使用我們之前在迭代器的文章中提到的所有的迭代器的操作,當我們使用指針加上或者減去一個整型的值時我們將會獲得一個新的指針,這個指針指向原來數(shù)組元素前或者后幾個位置的元素,具體的位置取決于加或者減的值:

constexpr size_t sz = 5;
int arr[sz] = {1, 2, 3, 4, 5};
int *p1 = arr; //等價于*p1 = &arr[0]
int *p2 = p1 + 4; //p2指向arr[4]

當我們用數(shù)組加上sz時,編譯器會把arr轉(zhuǎn)化為指向數(shù)組第一個元素的指針,所以如下p就是指向數(shù)組最后一個元素的下一個元素,如果相加結(jié)果超出數(shù)組的范圍則會發(fā)生錯誤:

int *p = arr + sz; //小心使用,沒有解引用
int *p3 = arr + 10; //錯誤,數(shù)組只有5個元素,雖然編譯器可能無法檢測到這個錯誤

和迭代器一樣,兩個指針相減其結(jié)果是兩個指針之間的距離,其前提是這兩個指針式同一個數(shù)組中的元素:

auto n = end(arr) - begin(arr);

解引用和指針的算術(shù)運算

通過上面的介紹我們已經(jīng)知道了指針也有算數(shù)運算,那么如何判斷是指針的算術(shù)運算還是元素的算術(shù)運算呢,可以和之前復雜的指針對應,都是先從括號內(nèi)部開始:

int ia = {0, 2, 4, 6, 8};
int last = *(ia + 4); //先看括號內(nèi),所以這是指針的元素暗,last = ia[4] = 8
int last2 = *ia + 4; //ia指向ia[0], 所以last2 = ia[0] + 4 = 4

下標與指針

我們可以看到數(shù)組其實就是一個指向數(shù)組第一個元素的指針,所以對于數(shù)組的下標操作其實就是對于指針的算數(shù)元運算,ia[2]等價于*(ia + 2):

int ia = {0, 2, 4, 6, 8};
int *p = &ia[2]; //p指向ia[2]的指針
int j = p[-2]; p[-2]等價于*(p - 2), 所以j = ia[0]
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2108

    瀏覽量

    73618
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    417

    瀏覽量

    25939
  • 迭代器
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    4307
收藏 人收藏

    評論

    相關(guān)推薦

    C++STL算法(二)

    C++STL算法(二)
    的頭像 發(fā)表于 07-18 14:49 ?1035次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>之</b>STL算法(二)

    c++STL算法(三)

    c++STL算法(三)
    的頭像 發(fā)表于 07-18 15:00 ?1279次閱讀
    <b class='flag-5'>c++</b><b class='flag-5'>之</b>STL算法(三)

    C++文件操作

    C++文件操作
    的頭像 發(fā)表于 07-21 10:52 ?1108次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>之</b>文件操作

    C/ C++/ Java 程序設(shè)計經(jīng)典教程》

    本帖最后由 圈圈7029 于 2014-11-13 11:41 編輯 《C/ C++/ Java 程序設(shè)計經(jīng)典教程》(Deitel 著)●集作者幾十年程序設(shè)計經(jīng)驗精華,從軟件工程
    發(fā)表于 11-13 11:22

    C++教程之數(shù)組

    C++教程之數(shù)組 新版的成績管理系統(tǒng)編輯某同學的7門功課成績分別為:88,89,90,75,76,64,95。設(shè)計一個程序求其平均成績,并增加查詢功能:即用戶選擇1
    發(fā)表于 05-15 17:59 ?45次下載

    C++入門基礎(chǔ)教程大全

    C++入門基礎(chǔ)教程大全 C++是一種面向?qū)ο蟮木幊陶Z言,但如果系統(tǒng)沒有采用面向?qū)ο蟮募夹g(shù),C++只能作為面向過程的語言來使用.
    發(fā)表于 05-29 10:25 ?0次下載

    C++ 入門自學教程

    C++ 入門自學教程從入門知識開始講起,比較有利于初學者入門掌握,比較好懂,能夠?qū)?b class='flag-5'>C++有一個全面認識
    發(fā)表于 11-17 10:36 ?0次下載

    C++實驗 數(shù)組的應用

    C++實驗 數(shù)組的應用
    發(fā)表于 12-30 15:04 ?0次下載

    C++語言入門教程之C++語言程序設(shè)計數(shù)組的詳細資料概述免費下載

    本文檔的主要內(nèi)容詳細介紹的是C++語言入門教程之C++語言程序設(shè)計數(shù)組的詳細資料概述免費下載內(nèi)容包括了:1 一維數(shù)組 2 二維
    發(fā)表于 09-20 14:51 ?9次下載
    <b class='flag-5'>C++</b>語言<b class='flag-5'>入門</b>教程之<b class='flag-5'>C++</b>語言程序設(shè)計<b class='flag-5'>數(shù)組</b>的詳細資料概述免費下載

    C語言入門教學數(shù)組資料總結(jié)免費下載

    本文檔的主要內(nèi)容詳細介紹的是C語言入門教學數(shù)組資料總結(jié)免費下載主要內(nèi)容包括了:1 一維數(shù)組的定義和一維
    發(fā)表于 10-23 17:53 ?5次下載
    <b class='flag-5'>C</b>語言<b class='flag-5'>入門</b>教學<b class='flag-5'>之</b><b class='flag-5'>數(shù)組</b>資料總結(jié)免費下載

    C++程序設(shè)計教程之數(shù)組的詳細資料說明

    本文檔詳細介紹的是C++程序設(shè)計教程之數(shù)組的詳細資料說明主要內(nèi)容包括了:1. 數(shù)組概念,2. 一維數(shù)組的定義和引用,3. 二維
    發(fā)表于 03-14 14:48 ?10次下載
    <b class='flag-5'>C++</b>程序設(shè)計教程之<b class='flag-5'>數(shù)組</b>的詳細資料說明

    C++入門表達式

    C++中提供了很多操作符且定義了什么時候可以用于操作基本類型,其還允許我們定義用于操作class類型的操作符,接下來幾篇文章將會介紹C++中用于基本類型的操作符,與此同時也會介紹一些庫中操作符。一個
    的頭像 發(fā)表于 03-17 13:55 ?797次閱讀

    ?數(shù)組C++ std::array詳解

    std::array是C++容器庫提供的一個固定大小數(shù)組的容器。其與內(nèi)置的數(shù)組相比,是一種更安全、更容易使用的數(shù)組類型。
    的頭像 發(fā)表于 07-19 11:02 ?1105次閱讀
    ?<b class='flag-5'>數(shù)組</b>和<b class='flag-5'>C++</b> std::array詳解

    動態(tài)數(shù)組C++ std::vector詳解

    std::vector是C++的默認動態(tài)數(shù)組,其與array最大的區(qū)別在于vector的數(shù)組是動態(tài)的,即其大小可以在運行時更改。std::vector是封裝動態(tài)數(shù)組的順序容器,且該容器
    的頭像 發(fā)表于 07-19 11:07 ?965次閱讀

    C++數(shù)組名和數(shù)組拷貝詳解

    C++數(shù)組間賦值不能直接通過數(shù)組名稱 randy = sesame進行,因為數(shù)組名并不是指針,大部分情況下,編譯器會隱式轉(zhuǎn)換為指向數(shù)組首元素
    發(fā)表于 08-21 15:09 ?460次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>數(shù)組</b>名和<b class='flag-5'>數(shù)組</b>拷貝詳解
    RM新时代网站-首页