第4章 數組和指標
現代C++程式應使用vector和迭代器代替數組和指標,除非前二者不滿足對效率的特殊要求
⒋⒈ 數組
⒈ 數組是由類型說明符、標識符和維度組成的複合類型,能儲存一組某種類型的未命名物件
⒉ 定義和初始化
⑴ 類型說明符規定了存放於數組中元素的類型
可使用除引用外的任意類型,包括數組本身(數組的數組即**數組)
⑵ 維數指定數組中包含的元素個數,須用值大於等於1的常量運算式定義,一經指定不可改變
⑶ 可以使用初值列表(用花括弧括起的一組用逗號分隔的初值,可為空白)顯式提供元素的初值
① 此時可不指定維數,數組長度將由初值列表中的元素個數自動確定
② 若指定維數:
ⅰ 維數值不能小於初值個數
ⅱ 若維數值大於初始化列表中提供的元素個數,則只用初值列表初始化數組中前面對應的元素
其餘元素,若為內建類型則初始化為0,若為類類型則調用預設建構函式
③ 對於**數組,除第一維外其餘維數都須顯示指定
初值列表可內嵌花括弧以指明各初值對應的位置,若不使用內嵌花括弧則依次初始化
⑷ 若未提供初值列表,則數組元素像普通變數一樣初始化
⑸ 使用字串字面值初始化字元數組時注意前者結尾隱含的Null 字元
⒊ 不允許數組直接複製和賦值
⒋ 數組元素可通過下標操作符[]訪問,下標從0開始
下標越界將導致執行階段錯誤
⒋⒉ 指標
⒈ 指標是一種能儲存對象地址的對象
⒉ 定義和初始化
⑴ 形式: 類型名* 標識符;
類型名指定指標指向對象的類型(類型名為 void 時指標可指向任意類型的對象)
① 連續聲明多個指標時,每個標識符前都要加*號
② 可以連續使用多個星號*表示指向指標的指標
③ const 限定符
ⅰ 指向 const 對象的指標
a形式: const 類型名* 標識符;
(或 類型名 const* 標識符;)
b const 對象只能與這種指標關聯
c不能通過這種指標修改所指對象,無論所指是否為 const
由於有此特性,該種指標常用作函數形參以防止所指對象被意外修改
ⅱ const 指標
a形式:類型名* const 標識符
b指標本身的值不能修改,即不能改變指向,但可以改變所指對象的值
ⅲ 指向 const 對象的
const 指標
a形式: const 類型名*
const 標識符
b既不能改變所指對象的值,也不能改變指向
ⅳ typedef T* pT; 則
const pT t 和 pT const t 均與 T*
const t 等價
④ 指向數組的指標
ⅰ 形式: 類型名 (*標識符)[維數][維數]..[維數];
ⅱ typedef 類型名新類型名[維數][維數]..[維數];
得到數群組類型的別名,可以此簡化定義
⑵ 應避免使用未初始化的指標
而一個有效指標必然為以下三種狀態之一:
① 儲存某確定對象的地址
② 指向一個對象的下一位置
③ 值為0
因此在對指標初始化和賦值時只能使用:
① 值為0的常量運算式
② 類型匹配的對象的地址(使用取地址操作符&獲得,該運算子只能對左值使用)
③ 另一對象下一位置的地址
④ 同類型另一有效指標
⒊ 指標操作
⑴ 使用解引用操作符*可以獲得指標指向對象的左值,從而操作所指對象
而對指標直接進行賦值等操作將改變指標本身的值,使指標指向另一對象
⑵ 指標可被當作數組的迭代器,用以訪問數組元素
① 指標的算術操作
ⅰ 指標與整型值相加(減),得到指向所指元素向後(前)移動相應位置的數組元素的新指標
ⅱ 兩個指向同一數組中元素的指標(含超出末端指標)相減,得到一個 ptrdiff_t 型(定義在標頭檔 cstddef 中,
signed 整型)結果,表示兩指標所指元素間的距離
② 對指標進行下標操作[],返回所指元素向後(前)移動相應位置的數組元素引用
③ 可以計算超出末端指標,但不允許對其進行解引用操作
計算越界指標也是非法的
⑶ void* 指標不支援以上操作
⒋⒊ C風格字串
⒈ C風格字串是以Null 字元結尾的字元數組
字串字面值就是其執行個體
⒉ C風格字串的標準庫函數(標頭檔 cstring)
傳給以下庫函數的須為指向以Null 字元結尾的字元數組的非零指標
⑴ size_t strlen(
char *str );
返回字串長度(不包括結尾的Null 字元)
⑵ int strcmp(
const char *str1,
const
char *str2 );
比較兩個字串,如果前者大於後者返回正數,小於返回負數,等於返回0
註:不能使用>,<,==操作符比較,它們只會比較存放地址而不會比較字串
⑶ char *strcat(
char *str1, const
char *str2 );
將str2串連到str1後面,並返回str1
此函數不進行越界檢查
⑷ char *strcpy(
char *to, const
char *from );
將str2複製到str1字串,並返回str1
此函數不進行越界檢查
⑸ char *strncat(
char *str1, const
char *str2,
size_t count );
將str2的前至多count個字元串連到str1後面,並返回str1
如果越界則截斷字串,因此比strcat安全
⑹ char *strncpy(
char *to, const
char *from,
size_t count );
將str2的前至多count個字元複製到str1,並返回str1
如果越界則截斷字串,因此比strcpy安全
⒊ 對於大部分程式而言,標準庫類型 string 無論安全性還是效率均強過C風格字串,因此應儘可能使用 string