C Primer Plus的若干收穫 (四)

2021-06-22 22:41:27 字數 4735 閱讀 4478

經過半個月的辛苦的學習,終於把那個該死的科目三給考過去了,真是太煎熬啊。又被曬黑了,不知道又要捂多久才能重新變過來。。。不過,好在自己抽空能夠看下c++時間也不算太難過。馬上要回學校了,一看自己才寫了三篇博文,簡直不能忍了。最近要加把油啊,一會學校事情可就多了。

1.1 檔案尾條件

如果輸入來自於檔案,則存在一種強大的技術來檢測檔案尾———檢測檔案尾eof。c++輸入工具和作業系統一起來檢測檔案尾,並將其告知程式。乍一看,讀取檔案中的資訊cin似乎和鍵盤輸入沒什麼關係,但其實有兩個相關的關係,首先很多作業系統都支援重定向,允許檔案代替鍵盤輸入;其次,很多作業系統都允許通過鍵盤來模擬檔案尾條件。在unix中可以在首行按下ctrl+d來實現,在windows下可以在任意位置按下ctrl+z和enter。總之,很多pc程式設計環境都將ctrl+z視為模擬的eof,但具體細節(在什麼位置以及是否需要按下enter)各不相同。

檢測到eof後,cin將兩位(eofbit與faiblt)都設定為1 。如果檢測到eof,則cin.eof()將返回bool值true,否則返回false。同樣,如果eofbit或failbit被設定為1,cin.fail()也會返回1 。因此將cin.fail()與cin.eof()測試放到讀取後以檢測檔案。

include using namespace std;

int main()

在這裡結合1.1 與1.2 來對其做乙個小結

cin.get()與cin.get(ch)

屬性cin.get(ch)

ch=cin.get()

傳遞輸入字元的方式

用於字元輸入時的函式返回值

istream物件

int型別的字元編碼

到達eof時的返回值

istream物件

eof

1.3 字元函式庫cctype

c++從c語言中繼承了乙個與字元相關的函式軟體包,他可以簡化諸如確定字元是否為大寫字母、數字、標點符號等工作,這些檔案是在標頭檔案cctype中定義的。這裡來對其中的一些函式進行總結。

函式名稱

返回值isalnum()

如果引數是字母或者是數字,該函式返回true

isalpha()

如果引數是字母,則會返回true

iscntrl()

如果引數是控制字元,則會返回true

isdigit()

如果引數是數字0~9,則會返回true

isgraph()

如果引數是如空格之外的列印字元,將會返回true

islower()

如果引數是小寫字母,則會返回true

isprint()

如果引數是列印字元(包括字元),則會返回true

ispunct()

如果引數是標點符號,則會返回true

isspace()

如果引數是標準的空白字元,如空格、換行符、回車、水平製表符或者是垂直製表符,該函式返回true

isupper()

如果引數是大寫字母,則返回true

isxdigit()

如果引數是十六進製制的數字,該函式返回true

tolower()

如果引數是大寫字母,將會返回他的小寫

toupper()

如果引數是小寫字母將會返回它的小寫

1.4 c++的內聯函式

編譯過程的最終產品是可執行的程式————有一組機器語言組成。程式執行時,作業系統將這些指令載入到計算機中,因此每條指令都有特定的記憶體位址。計算機隨後會逐條執行這些指令。有時(如有迴圈或者分支語句時),將跳過一些指令,向前或向後跳過一些位址。常規函式呼叫時也使程式跳到另乙個位址,並將在函式結束時返回。下面更詳細的介紹著一典型過程。執行到函式呼叫指令時,程式將在函式呼叫時立即儲存該指令的記憶體位址,並將函式複製到堆疊中,標記函式起點的記憶體單元,執行函式**,然後跳回到位址被儲存的指令處(這與閱讀文章時停下來看腳注,並在看完腳注時又回到以前閱讀的地方類似)。

c++內聯函式提供了另一種選擇。內聯函式的編譯**與其他程式的**內聯起來了。對於內聯**,程式無需跳到另外乙個地方去執行**,再跳回來。因此內聯函式執行的速度比常規的稍快,但代價是要占用更多的記憶體。如果程式在十個不同的地方呼叫同乙個內聯函式,在該函式將要包含該函式的十個副本。

另外,當程式設計師請求將函式作為內聯函式時,編譯器不一定會滿足這樣的要求。它可能認為該函式過大或該函式呼叫了自己(內聯函式不能遞迴),因此不能作為內聯函式。下面給乙個小例子

inline double square(double x)

int main()

1.5 建立引用變數

我們要將rodents作為rats的別名,可以這樣做:

int rats;

int & rodents=rats;

其中&不是位址運算子,而是型別標示符的一部分。就像生命中的char*指的是指向char的指標一樣,int&指的是只想int的引用。上述的宣告允許將rats與rodents互換————他們只想相同的記憶體位址。

對於c語言使用者而言,首次接觸到引用是可能會有些困惑,會很自然的想到指標,但是他們之間還是有區別的。比如

int rats=101;

int & rodents=rats;

int *prats=&rats;

這樣,表示式rodents和*prats都可以與rats互換,而表示式&rodents與prats都可以和&rats互換。從這一點來看,引用很像偽裝起來的指標,實際上,引用還是不同於指標的。差別之一是,必須在宣告引用時將其初始化,而不能想指標那樣先宣告再賦值。

1.6 將引用作為函式引數

引用經常被用作函式的引數,是得函式中的變數名稱為呼叫程式中的變數的別名。這種傳遞引數的方法稱為引用傳遞。按引用傳遞允許被呼叫的函式訪問呼叫函式中的變數。c語言只能按值傳遞,按值傳遞導致被呼叫的函式使用呼叫程式中的值的拷貝。當然,c語言也有避開這種按值傳遞方式的限制,採用按指標傳遞的方法。下面我們以交換兩個值為例,來對指標和引用做乙個對比

void swapr(int * a,int * b)//use pointers

void swapr(int & a,int & b)//use references

void swapr(int a,int b)//use pointers//can't use
如果程式設計師的意圖是讓函式使用傳遞給他的資訊而不是修改它,同時又想使用引用,則應該使用常量引用呼叫。

double refcube(const double &ra);
如果這樣做,當編譯器發現**修改ra的值時,將生成錯誤的資訊。

1.7 臨時變數、引用引數和const

如果實參與引用引數不匹配,c++將生成臨時變數。當前,僅當引數為const時,c++才允許這樣做,下面來看看何種情況下c++將生成臨時變數,以及何時對const引用的限制是合理的。

首先,什麼是建立臨時變數呢?如果引用引數為const型,則編譯器將在下面兩種情況下生成臨時變數:

左值是什麼?左值引數是可以被引用的資料物件。例如,變數、陣列元素、結構成員和解除引用的指標都是左值。非左值包括字面常量和包含多項的表示式。

應盡可能使用const

將引用引數宣告為常量資料的引用理由有三個:1.使用const可以避免無意中修改資料的變成錯誤;2.使用const使函式能夠處理const和非const實參,否則將只能接受非const的資料;3.使用const引用是函式能夠正確生成和使用臨時變數。

這裡介紹一下將引用用於結構的情況,先看下如下的**:

struct free_throws

;

void display(const free_throws& ft)

有關結構體的相關介紹我就不再這裡累贅了。下面我們來看看這條語句

free_throws& accumulate(free_throws& target,const free_throws& source)

如果返回型別被宣告為free_throws而不是free_throws&,上述返回語句將返回target的拷貝。但返回的型別為引用,這意味著返回的是最初傳遞給函式的結構體物件。比如

dup=accumulate(team,five);
如果accumulate()返回的是乙個結構,而不是指向結構的引用,將把整個結構複製到乙個臨時的位置,再將這個拷貝複製給dup。擔當返回值為引用時,將直接把team複製給dup,其效率更高。

不過在返回引用時也需要注意一些問題,應避免返回資料終止時不再存在的記憶體單位引用。您因避免有如下的**

const free_throws& clone2(free_throws& ft)

該函式返回乙個指向臨時變數的引用,函式執行完畢後他將不再存在。為避免這種問題最簡單的方法是返回乙個作為引數傳遞給函式的引用。作為引數的引用將指向呼叫函式使用的資料,因此返回的引用也將指向這些資料。另一種方法是用new來分配新的儲存空間,但是當我們不再需要這個結構時應該使用delete將其釋放。

C Primer Plus的若干收穫 (二)

哎,真是不想吐槽考駕照的艱辛歷程了。跑到大西郊,頂著大太陽,一天就能摸上個十幾分鐘二十分鐘的車,簡直不要太坑爹,這兩天真是做的我屁股疼的不行。今天果斷不去了。只可惜我的大阿根廷啊,堅持到最後功虧一簣惜敗於德國,枉我四點自然醒起來看了接下來的比賽。不能不佩服諾伊爾,拉姆,博阿滕組成的後防線,讓阿根廷整...

C Primer Plus的若干收穫 (三)

有時候懷疑真是懷疑自己走的路到底是不是正確的。作為乙個土生土長數學系學生,卻對數學毫無興趣,沒事的時候就喜歡躲在圖書館看看有關計算機的書。有時候期末考試時候會掛個一兩門的數學專業課,有時候真希望數學課本上這乙個個繁瑣的證明是用 寫的。自己幾乎丟掉了本專業的一切,去全身心投入到計算機這一龐大而繁瑣的學...

C Primer Plus的若干收穫 (七

這篇博文主要講了命名空間,說實話在接觸之前一直對這方面很感興趣,現在來好好的學習一番。7.1 新的命名空間特性 c 新增了這樣一種功能,即通過定義一種新的宣告區域來建立命名的命名空間,這樣做的目的之一是提供乙個宣告名稱的區域。乙個命名空間的名稱不會與另外乙個空間的名稱發生衝突,同時允許程式的其他部分...