只是記了一部分我認為比較難理解的,或常用的,部分掌握的就沒有寫。
【規則 7-2-1】用 malloc 或 new 申請記憶體之後,應該立即檢查指標值是否為 null。 防止使用指標值為 null 的記憶體。
【規則 7-2-2】不要忘記為陣列和動態記憶體賦初值。防止將未被初始化的記憶體作為右 值使用。
【規則 7-2-3】避免陣列或指標的下標越界,特別要當心發生「多 1」或者「少 1」 操作。
【規則 7-2-4】動態記憶體的申請與釋放必須配對,防止記憶體洩漏。
【規則 7-2-5】用 free 或 delete 釋放了記憶體之後,立即將指標設定為 null,防止產 生「野指標」
以字串為例比較指標與陣列的特性。
示例 7-3-1 中,字元陣列 a 的容量是 6 個字元,其內容為 hello\0。a 的內容可以改變, 如 a[0]= 『x』。
指標 p 指向常量字串「world」(位於靜態儲存區,內容為 world\0),常 量字串的內容是不可以被修改的。
從語法上看,編譯器並不覺得語句 p[0]= 『x』有什麼 不妥,但是該語句企圖修改常量字串的內容而導致執行錯誤
char a = "內容複製與比較hello";
a[0] = 'x'
;cout
<< a <
char *p = "
world
"; //
注意 p 指向常量字串
p[0] = '
x'; //
編譯器不能發現該錯誤
cout << p << endl;
計算記憶體容量:
char a = "7.4指標引數是如何傳遞記憶體的hello world";
char *p =a;
cout
<< sizeof(a) << endl; //
12 位元組
cout<< sizeof(p) << endl; //
4 位元組
void func(char a[100])
看下面的幾個例子, 好多筆試題遇見過這幾個例子
例一:
void getmemory(char *p)例二:void test(void
)請問執行 test 函式會有什麼樣的結果?
答:程式崩潰。
因為 getmemory 並不能傳遞動態記憶體,
test 函式中的 str 一直都是 null。
strcpy(str,"
hello world
");將使程式崩潰。
void getmemory(char **p, int例三:num)
void test(void
)請問執行 test 函式會有什麼樣的結果?
答: (1
)能夠輸出 hello
(2)記憶體洩漏 (沒有加free函式)
char *getmemory(void例四:)void test(void
)請問執行 test 函式會有什麼樣的結果?
答:可能是亂碼。
因為 getmemory 返回的是指向「棧記憶體」 的指標,
該指標的位址不是 null,但其原 現的內容已經被清除,新內容不可知
void test(void7.6:動態分配的記憶體會自動釋放嗎?)}請問執行 test 函式會有什麼樣的結果?
答:篡改動態記憶體區的內容,後果難以預料,非常危險。
因為free(str);之後,str 成為野指標, if(str != null)語句不起作用。
void getmemory(char *p)我們發現指標有一些「似是而非」的特徵:
(1)指標消亡了,並不表示它所指的記憶體會被自動釋放。
(2)記憶體被釋放了,並不表示指標會消亡或者成了 null 指標。
7.7野指標
「野指標」不是 null 指標,是指向「垃圾」記憶體的指標
造成野指標出現的原因:
(1)指標變數沒有被初始化。例如:char *p; 這個就是野指標,應該修改為char *p = null;
(2)指標 p 被 free 或者 delete 之後,沒有置為 null
7.11new和delete的使用要點:
int *p1 = (int *)malloc(sizeof(int) *length);如果 c++程式要呼叫已經被編譯後的 c 函式int *p2 = new
int[length];
delete
p2;如果用
new建立物件陣列,那麼只能使用物件的無引數建構函式。
obj *objects = new obj[100]; //
建立 100 個動態物件
在用 delete
釋放物件陣列時,留意不要丟了符號『』。例如
delete objects; //
正確的用法
delete objects; //
錯誤的用法
後者相當於 delete objects[0],漏掉了另外 99 個物件。
假設某個 c 函式的宣告如下:
void foo(int x, int y);
該函式被 c 編譯器編譯後在庫中的名字為_foo,而c++編譯器則會產生像_foo_int_int 之類的名字用來支援函式過載和型別安全連線。
由於編譯後的名字不同,c++程式不能 直接呼叫 c 函式。
c++提供了乙個 c 連線交換指定符號 extern「c」來解決這個問題。
extern「c」
或者:
extern 「c」這就告訴 c++編譯譯器,函式 foo 是個 c 連線,應該到庫中找名字_foo 而不是找 _foo_int_int。
c++編譯器開發商已經對 c 標準庫的標頭檔案作了 extern「c」處理,所以我 們可以用#include 直接引用這些標頭檔案
注意並不是兩個函式的名字相同就能構成過載。全域性函式和類的成員函式同名不算 過載,因為函式的作用域不同
呼叫時要加上作用域運算子
class建構函式的列表初始化:string
;
如果類存在繼承關係,派生類必須在其初始化表裡呼叫基類的建構函式。
拷貝建構函式和賦值函式,當涉及到預設的含有記憶體操作時,要注意。
。以類 string 的兩個物件 a,b 為例,假設 a.m_data 的內容為「hello」, b.m_data 的內容為「world」。
現將 a 賦給 b,預設賦值函式的「位拷貝」意味著執行 b.m_data = a.m_data。
這將造成三個錯誤:
一是 b.m_data 原有的記憶體沒被釋放,造成記憶體洩露;
二是 b.m_data 和 a.m_data 指向同一塊記憶體,a 或 b 任何一方變動都會影響另一方;
三是 在物件被析構時,m_data 被釋放了兩次。
string類的成員函式實現:
// string 的普通建構函式string::string(const
char *str)
else
}
// string 的析構函式
string::~string(void拷貝構造和賦值函式)
//拷貝建構函式
string::string(const string &other)
//賦值函式
string &string::operate =(const string &other)
《高質量程式設計指南 C C語言》 林銳
一 c 檔案結構 c c 程式的標頭檔案以 h 為字尾,c 程式的定義檔案以 c 為字尾,c 程式 的定義檔案通常以 cpp 為字尾 1 標頭檔案結構 h 標頭檔案由三部分內容組成 1 標頭檔案開頭處的版權和版本宣告。2 預處理塊。3 函式和類結構宣告等。為了防止標頭檔案被重複引用,應當用ifnde...
c c 高質量程式設計(林銳)讀書筆記二
標頭檔案由三部分內容組成 1 標頭檔案開頭處的版權和版本宣告 參見示例1 1 2 預處理塊。3 函式和類結構宣告等。假設頭檔名稱為graphics.h,標頭檔案的結構參見示例1 2。規則1 2 1 為了防止標頭檔案被重複引用,應當用ifndef define endif結構產生預處理塊。規則1 2 ...
高質量C C程式設計指南
1.如果引數是指標,且僅作輸入用,則應在型別前加const,以防止該指標在函式體內被意外修改 2.在函式體的 入口處 對引數的有效性進行檢查 在函式體的 出口處 對return語句的正確性和效率進行檢查 3.引用的一些規則如下 1 引用被建立的同時必須被初始化 指標則可以在任何時候被初始化 2 不能...