Exceptional C 學習筆記1

2021-07-23 08:53:24 字數 2931 閱讀 1169

第一條 vector的使用

1 v[i] 與 v.at[i]

這個知識點主要是講用和at訪問vector元素的區別。如果的話,因為標準並沒有要求它做範圍檢查,所以效率較高,但訪問越界不會丟擲異常,可能會產生未定義行為。如果是用at的話,該成員函式會進行下標越界檢查,所以越界時會丟擲異常out_of_range。

2 調整vector大小 v.size()  v.capacipy()

size是當前vector容器真實占用的大小,也就是容器當前擁有多少個元素。它沒有告訴你容器為它容納的元素分配了多少記憶體。

capacity告訴你容器在它已經分配的記憶體中能容納多少元素。 如果你想知道乙個vector中有多少沒有被占用的記憶體,你必須從capacity()中減去size()。如果size和capacity返回同樣的值,容器中就沒有剩餘空間了,而下一次插入(通過insert或push_back等)會引發realloc(重新分配)。  

當然,這兩個屬性還分別對應兩個方法:resize()和reserve()。

使用resize(n),容器內的物件記憶體空間是真正存在的。它會強制把容器改為容納n個元素。呼叫resize之後,size將會返回n。如果n小於當前大小,容器尾部的元素會被銷毀。如果n大於當前大小,新預設構造的元素會新增到容器尾部。如果n大於當前容量,在元素加入之前會發生重新分配。 

使用reserve(n)僅僅只是修改了capacity的值,容器內的物件並沒有真實的記憶體空間(空間是"野"的)。強制容器把它的容量改為至少n,提供的n不小於當前大小。這一般強迫進行一次重新分配,因為容量需要增加。(如果n小於當前容量,vector忽略它,這個呼叫什麼都不做

下面用例子進行說明:

[cpp] view plain

copy

#include 

#include 

usingstd::vector;  

intmain(void)  

執行結果為:(win 10 + vs2010)

補充: 在stl中,擁有capacity屬性的容器只有vector和string。

與size相關的還有乙個max_size,它是編譯器最大的能申請到的元素個數,結果會是乙個非常非常大的值。

如果sizeof乙個vector物件,結果會是多少呢?

由於vector應該是從堆上分配記憶體,所以sizeof的大小與元素個數無關,只取決於vector裡面存放的資料型別,該值應該是與編譯器相關的。在win10+vs2013下測試結果是16。指的應該是vector的四個指標型別成員變數:iterator _first, _last, _end;所以會有16個位元組

3 **風格

類似於指標,const vector::iterator中,const是修飾的迭代器,也就是是個常迭代器,一旦初始化比如=a.begin(),再不能更改它的值,比如賦值=a.end()是不行的,遞增遞減操作等都不允許。雖然類似指標,但指標是內建型別,所以編譯器可以通過const的位置來判斷是常指標還是指向常量的指標,而迭代器只是乙個物件,所以編譯器不能分辨,所以用const_iterator來取代指向常量的指標,使用它,你通過這個迭代器對迭代器所指向的內容進行改寫是非法的。

盡量使用!=而不是《來比較兩個迭代器

盡量用字首形式的--和++

避免無謂的重複求值。這個我也經常做不到,但是這樣可以少定義乙個臨時變數,當不要求效率時,我喜歡用重複求值。

盡量使用\n而不是endl。記住endl會重新整理緩衝區,如果你不要求重新整理的話,就用\n。

盡量使用標準庫中的copy()和for_each(),而不是自己手寫迴圈。

第2條 字串格式化的「動物樂園」之一:sprintf

筆者簡介:    

sprintf()主要功能是把格式化的資料寫入某個字元緩衝區

int sprintf( char *buffer, const char *format, [ argument] … );

buffer:char型指標,指向將要寫入的字串的緩衝區。

format:格式化字串。

[argument]...:可選引數,可以是任何型別的資料。

返回寫入buffer 的字元數,出錯則返回-1. 如果 buffer 或 format 是空指標,且不出錯而繼續,函式將返回-1,並且 errno 會被設定為 einval。

sprintf 返回被寫入buffer 的位元組數,結束字元『\0』不計入內。即,如果「hello」被寫入空間足夠大的buffer後,函式sprintf 返回5

作者對sprintf進行了評價:

1.易用性與清晰性都不錯

2.效率最佳(我有好幾次效能問題都是格式化引起的,當我可以保證不越界的情況下,我會毫不猶豫的用它

3.長度安全性(沒有,是引起緩衝區溢位出錯的原因之一)

4.型別安全性(沒有,對於sprintf來說,型別錯誤就意味著執行時錯誤,而非編譯錯誤。printf家族使用c的可變引數列表,c編譯期間通常不檢查這類實參列表的型別

5.模板親和性(沒有)

snprintf函式是sprintf函式的更加安全版本,考慮到字串的位元組數,防止了字串溢位。函式形式為:int snprintf(char *restrict buf, size_t n, const char * restrict  format, ...);。最多從源串中拷貝n-1個字元到目標串中,然後再在後面加乙個0。所以如果目標串的大小為n 的話,將不會溢位。

Exceptional C 學習筆記(2) 多型

第5條 泛型性的風味之一 基礎 1c 模板提供了編譯期多型的能力 說到物件導向特性之一 多型 通常指常規的多型,即通過虛函式實現的 動態多型 或者叫 執行期多型 而該條款說的模板提供的 編譯期間多型 也可以叫 靜態多型 首先介紹下執行多型 執行多型可以簡單地概括為 乙個介面,多種方法 程式在執行時才...

C Primer Chapter One學習筆記

筆記 1.流 從io裝置上讀入或寫出的字串行,用來說明字元隨時間順序生成或消耗。2.輸入輸出符可連用原因 operator 或operator 返回stream物件。3.要測試程式那個語句出錯,使用cout 4.新建乙個內建型別,如int i 0 最好先初始化,不然用到的時候沒初始化會產生奇怪的錯誤...

BroadcastReceiver學習筆記

需要注意 的是,不要在 onreceive 方法中新增過多的邏輯或者進行任何的耗時操作,因為在廣播接收 器中是不允許開啟執行緒的,當 onreceive 方法執行了較長時間而沒有結束時,程式就會報錯。有序broadcast,sendorderedbroadcast intent,null abort...