C++中的數組和字符串是處理數據集合和文本的基礎工具。數組用于存儲相同類型的元素集合,而字符串則專門用于處理文本數據。C++提供了兩種主要的字符串處理方式:C風格字符串(字符數組)和C++的std::string
類。
📊 1. 數組 (Arrays)
數組是相同類型元素的集合,這些元素在內存中連續存儲。數組的大小在定義時確定,且不能改變。
一維數組
-
聲明與初始化。
數組的聲明需要指定元素類型、數組名和大小。初始化可以在聲明時進行。
int numbers[5];// 聲明一個包含5個整數的數組,未初始化int numbers[5] = {1, 2, 3, 4, 5};// 聲明并初始化int numbers[] = {1, 2, 3, 4, 5};// 編譯器自動計算大小
如果初始化值少于數組元素,剩余元素會自動初始化為0(對于基本數據類型)
-
訪問元素
通過索引訪問數組元素,索引從0開始。
int first = numbers[0];// 訪問第一個元素 numbers[4] = 10;// 修改第五個元素
-
特點
- 內存連續,訪問高效。
- 大小固定,無法動態擴容。
- 需注意數組越界訪問,這可能引發未定義行為。
多維數組
多維數組,如二維數組,可視為“數組的數組”,常用于表示矩陣或表格。
-
聲明與初始化
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};// 2行3列int matrix[2][3] = {1, 2, 3, 4, 5, 6};// 按順序初始化
-
訪問元素
使用多個索引訪問元素。
int value = matrix[1][2];// 訪問第二行第三列(值為6)
動態數組
使用new
和delete[]
在堆上動態分配和釋放內存。
int size = 5;
int* dynamicArray = new int[size];// 動態分配// 使用 dynamicArray...delete[] dynamicArray;// 釋放內存
動態數組需手動管理內存,防止內存泄漏。
🔤 2. 字符串 (Strings)
C++中有兩種主要的字符串表示方式:C風格字符串和std::string
類。
C風格字符串 (C-Style Strings)
C風格字符串本質是以空字符'\0'
結尾的字符數組
。
-
聲明與初始化。
char str1[] = "Hello";// 編譯器自動添加'\0',數組長度為6char str2[6] = {'H', 'e', 'l', 'l', 'o', '\0'};// 手動添加終止符
字符串字面量用雙引號括起,編譯器會自動在其末尾添加空字符
-
常用函數。
使用C標準庫函數(需包含
<cstring>
)進行操作:#include <cstring>char str1[20] = "Hello"; char str2[] = "World";strlen(str1);// 獲取字符串長度(不包括'\0')strcpy(str1, str2);// 復制字符串(需確保目標空間足夠)strcat(str1, "!");// 連接字符串(需確保目標空間足夠)strcmp(str1, "Hello World!");// 比較字符串(相等返回0)
注意:使用
strcpy
、strcat
等函數時,必須確保目標字符數組有足夠的空間,否則可能導致緩沖區溢出
std::string類
C++標準庫提供的std::string
類(需包含<string>
頭文件)封裝了字符串操作,自動管理內存,更安全便捷
。
-
聲明與初始化
#include <string> std::string s1;// 空字符串 std::string s2 = "Hello, World!";// 初始化std::string s3(s2);// 拷貝構造
-
常用操作
std::string
支持豐富的操作:s1 = "Hello"; s2 = "World"; std::string s4 = s1 + ", " + s2;// 字符串拼接(使用+運算符) s1.append(" World!");// 追加字符串int len = s1.length();// 或 s1.size(),獲取字符串長度char ch = s1[0];// 通過索引訪問字符(不檢查邊界) ch = s1.at(0);// 使用at()訪問(會檢查邊界,越界拋出異常)std::string sub = s1.substr(7, 5);// 提取子串(從位置7開始,長度為5)size_t pos = s1.find("World");// 查找子串,返回首次出現的位置(未找到返回std::string::npos) s1.replace(7, 5, "C++");// 替換子串(從位置7開始,替換5個字符為"C++") s1.insert(7, "Beautiful ");// 插入字符串 s1.erase(7, 10);// 刪除子串(從位置7開始,刪除10個字符)if (s1 == s2) {/* 比較字符串 */ }// 支持關系運算符比較
-
輸入輸出。
使用
getline
讀取整行文本(包括空格):std::string name; std::cout << "Enter your full name: "; std::getline(std::cin, name);// 讀取整行 std::cout << "Hello, " << name << std::endl;
使用
cin
進行輸入時,遇到空格、制表符或換行符會停止讀取
轉換
-
std::string
與 C風格字符串互轉。std::string s = "Hello"; const char* cstr1 = s.c_str();// 轉換為C風格字符串(只讀,指向s的內部數據)const char* cstr2 = s.data();// C++17前與c_str()類似,C++17起可能不以空字符結尾char arr[20]; std::strcpy(arr, s.c_str());// 將s的內容復制到可修改的字符數組arr中const char* cstr = "World"; std::string s_from_c = cstr;// C風格字符串轉換為std::string
注意:
c_str()
返回的指針在std::string
對象發生修改后可能失效
?? 3. 對比與選擇
特性 | C風格字符串 | std::string |
---|---|---|
內存管理 | 手動管理,易出錯 | 自動管理,避免泄漏 |
安全性 | 易緩沖區溢出/越界 | 更安全,邊界檢查 |
功能 | 基礎函數(strlen, strcpy等) | 豐富方法(拼接、查找、替換等) |
性能 | 開銷小,適合底層或嵌入式 | 動態擴容可能帶來開銷,但通常更便捷 |
建議:在現代C++開發中,優先使用std::string
,除非在與C代碼交互或對性能有極端要求的場景下才考慮使用C風格字符串
。
💡 4. 注意事項
- 數組越界:訪問數組時,確保索引在
[0, size-1]
范圍內,越界訪問會導致未定義行為。 - 字符串結束符:操作C風格字符串時,務必確保其以
'\0'
結尾,否則相關字符串函數可能無法正常工作甚至導致程序崩潰。 - 空間充足:對C風格字符串進行拼接、復制等操作前,務必確認目標字符數組有足夠的空間,防止緩沖區溢出。
std::string
的c_str()
:不要存儲c_str()
返回的指針并在后續修改std::string
對象,除非已重新獲取。該指針指向的數據可能在std::string
修改后失效。
掌握數組和字符串的基礎知識是進行有效C++開發的關鍵。根據具體場景選擇合適的工具,并始終牢記安全操作的準則。