【C++養成計劃】深入數組和字符串(Day8)

寫在前面:大家好!我是【AI 菌】,一枚愛彈吉他的程序員。我熱愛AI、熱愛分享、熱愛開源! 這博客是我對學習的一點總結與記錄。如果您也對 深度學習、機器視覺、算法、Python、C++ 感興趣,可以關注我的動態,我們一起學習,一起進步~
我的博客地址爲:【AI 菌】的博客

上一篇:【C++養成計劃】玩轉數字——數學運算函數/隨機數(Day7)
昨天,我們學習了對有關數字的一常用些操作;今天來一起探索C++中兩種最基本的數據結構:數組和字符串。



1. 初探數組

(1) 什麼是數組

在C++中,數組讓你可以按照順序將一系列相同類型的數據存儲到內存中。
數組具有如下幾個特點:

  • 數組是一系列元素
  • 數組中所有元素的類型都相同
  • 這組元素組成一個完整的集合

(2) 數組的存儲方式

在這裏插入圖片描述
數組的存儲方式和圖書館中存放書的方式是類似的。想想書架上某一排上存放的書籍,這就是一個一維數組,因爲它只沿着一個維度延伸。每本書都是一個數組元素,而書架就是爲存儲這些書籍而預留的內存。

同樣的道理,整個書架就是一個二維數組,因爲它不僅可以沿着橫向延伸,還能沿着縱向延伸。那麼一個圖書室就可以看成是一個三維數組,因爲一個圖書室有很多個書架,每個書架還能按行和列擺放不同書籍,可以從3個不同維度延伸。如此說來,整個圖書館有很多個圖書室,因此它可以沿着4個維度延伸,所以圖書館可看作是一個四維數組。依次類推,可以舉例出n維數組。

存儲數據的空間大小,也就類似於書佔書架的位置多少。不同的是,數組中每一個元素所佔用的空間大小是相同的,因爲數組中所有元素的類型都相同。元素所佔用的空間大小與元素的類型有關。比如一個int類型的元素佔用4個字節的空間,一個double類型的元素佔用8個字節的空間。

(3) 聲明和初始化數組

數組聲明
在 C++ 中要聲明一個數組,需要指定元素的類型type、數組的名稱arrayName和數組的長度length(也叫元素的個數),如下所示:

type arrayName[length];

例如,要聲明一個元素類型爲int,個數是5的數組ArrayNums

int ArrayNums[5];

數組初始化
在聲明數組時,還能對數組初始化。將ArrayNums裏的5個元素分別初始化一個值。

int ArrayNums[5]={8, 16, 32, 64, 128};

當然,也可以只對前面幾個元素進行初始化,如下所示:

int ArrayNums[5]={8, 16}; //初始化前兩個數

注:這裏所聲明的數組都是靜態數組,即它們的長度都是固定的。

(4) 訪問數組中的數據

訪問數組中的元素,要使用從0開始的索引。比如存儲在數組ArrayNums中的一個元素是ArrayNums[0],第二個元素是ArrayNums[1],依次類推。
訪問數組時,不能超越其邊界,否則結果是無法預料的。在很多情況下,這將導致程序崩潰。比如你可以在只包含5個元素的數組中取回索引爲10的元素,但這樣會給程序帶來安全和穩定性方面的風險。
下面舉一個簡單的例子,聲明並初始化一個int數組,並將其元素顯示在屏幕上。

#include<iostream>
using namespace std;

int main() 
{
	int ArrayNums[5]={8, 16, 32, 64, 128};
	for(int i=0;i<5;i++)
		cout<<ArrayNums[i]<<endl; //逐一輸出每一個元素 
	return 0;
} 

運行結果:
在這裏插入圖片描述
除此之外,我們還可以修改數組中的數據。比如我們已經聲明並初始化了一個數組ArrayNums,現在想修改數組中的第三個元素,可按如下方式進行賦值:

ArrayNums[2]=10; //將ArrayNums數組中第三個元素改爲10

2. 多維數組

大於或等於2維的數組都稱爲多維數組,我們這裏以最常見的二維數組進行講解。

(1) 聲明和初始化

多維數組聲明
在C++中,要聲明多維數組,可指定每維包含的元素數。比如,一個書架有2排,每排可以存放5本書,那麼就可以按如下聲明這個書架(二維數組):

int Bookshelf[2][5];

多維數組初始化
如果想給每本書指定(初始化)一個名稱,假設這10本書的名稱分別爲0~9,則可按如下方式進行初始化:

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

同樣,你也可以按如下方式進行初始化:

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

然而,第一種初始化方式更好,因爲它能讓你更容易看出數組的結構。

(2) 訪問多維數組的元素

和一維數組一樣,訪問數組中的元素,要使用從0開始的索引。比如書架第1排上的第2本書是Bookshelf[0][1],第2排上的第5本書就是Bookshelf[1][4]。
下面演示一個簡單的例子,在屏幕上顯示出書架上每一本書的名稱:

#include<iostream>
using namespace std;

int main() 
{
	int Bookshelf[2][5]={{0, 1, 2, 3, 4}, {5, 6, 7, 8, 9}};
	for(int i=0;i<2;i++)
	{
		for(int j=0;j<5;j++)
			cout<<Bookshelf[i][j]<<" "; //逐一輸出每一個元素 
		cout<<endl;
	}
	return 0;
} 

運行結果:
在這裏插入圖片描述

3. 動態數組

在前面我們聲明的一維數組和二維數組都屬於靜態數組。靜態數組的特點是,在數組聲明時就確定了數組元素的個數,且在後期不能再改變。

但是在實際問題中,可能無法在一開始就能確定數組的長度。比如,要在應用程序中存儲圖書館中的圖書信息,你無法知道需要處理圖書的上限數。就小圖書館來說,爲穩妥起見,你可以對上限做合理的假設。但是在這種情況下,將預留大量的內存,從而降低了系統的性能。

爲了減少佔用的內存,可不使用前面介紹的靜態數組,而使用動態數組,並在運行階段根據需要調整數組大小。C++提供了std::vector類,這是一種方便且易於使用的動態數組。
想更深入瞭解vector類的用法和各種騷操作,可以戳戳這裏:動態數組類:vector

注:對類等概念還不太瞭解的同學,此小節可先暫時不掌握;待後面我講完類,可再來學習。

4. C風格字符串

(1) C風格字符串中的風險

C 風格的字符串起源於 C 語言,並在 C++ 中繼續得到支持,是一種特殊的字符數組。字符串實際上是使用空字符 ‘\0’ 終止的一維字符數組。

下面我們採用C風格字符串,創建了一個 “Hello World” 。

char SayHello[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0'};

請注意,該數組的最後一個字符爲空字符‘\0’。這也被稱爲字符串結束字符,因爲它告訴編譯器字符串到此結束。這種C風格字符串是特殊的字符數組,因爲總是在最後一個字符後加上空字符‘\0’。
當在初始化字符數組時忘記添加‘\0’,打印該數組時,Hello World後面會出現垃圾字符。如下所示:

#include<iostream>
using namespace std;

int main() 
{
	char SayHello[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0'};
	cout<<"加空字符輸出:"<<SayHello<<endl;
	char SayHello1[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'};
	cout<<"不加空字符輸出:"<<SayHello1<<endl;
	char SayHello2[] = "Hello World"; 
	cout<<"字符串形式輸出:"<<SayHello2;
	return 0;
} 

運行結果如下:

在這裏插入圖片描述
分析:
第一行,末尾加了空字符’\0’的字符數組,輸出情況正常。
第二行,末尾沒加‘\0’的字符數組,輸出情況異常,如圖中紅色框所示,出現了垃圾字符。
第三行,使用字符串常量的形式,可以省去末尾的’\0’,輸出仍然正常。這是因爲C++ 編譯器會在初始化數組時,自動把 ‘\0’ 放在字符串的末尾。

對比可知,使用C風格字符串——一維字符數組,要特別注意空字符‘\0’的使用;否則在有些情況下,可能會引起程序崩潰,影響系統的穩定性。而使用C++中的字符串類string可以避免這些問題。

(2) C風格的字符串函數

C++中的cstring類中提供了很多實用的字符串函數,如下表所示:
在這裏插入圖片描述
在使用這些函數時,程序前面需要加上頭文件:

#include <cstring>

下面舉個簡單的例子,使用上述的一些函數:

#include<iostream>
#include<cstring>
using namespace std;

int main() 
{
	char str1[] = {'H','e','l','l','o',' ','\0'};
	char str2[] = {'C','p','p','\0'};
	strcat(str1,str2);
	cout<<"連接:"<<str1<<endl;
	cout<<"連接後的長度:"<<strlen(str1)<<endl;
	return 0;	
} 

運行結果:
在這裏插入圖片描述
注意:這些C風格字符串作爲輸入的函數非常危險,因爲它們會尋找終止空字符‘\0’,如果程序員沒有在字符數組末尾添加空字符,這些函數將跨越字符數組邊界。

5. C++中的String類

爲了避免以上的問題,C++提供了string類,這是一種功能強大而安全的字符串操作方式。無論是處理文本輸入,還是執行拼接等字符串操作,使用這些C++標準字符串都是效率最高的方式。

詳細瞭解String類的用法和各種騷操作,可以看我之前寫的兩篇博文,這裏不再贅述。
第一篇:C++:string類的基本用法(一)
第二篇:C++:常用的string類字符串函數(二)

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