《C++PrimerPlus 6th Edition》第5章 循環和關係表達式 要點記錄
爲節約時間,我把書中一些做了標註的地方按順序羅列下來。
循環類型:①入口條件循環:for、while;②do-while
-
格式規範:C++中,通常在for和括號之間加一個空格,而省略函數名與括號之間的空格
for (i = 6; i < 10; ++i) //for和括號之間加一個空格 smart_function(i); //函數名與括號之間無空格
-
cout.setf(ios:: boolalpha);
:設置了一個標記,該標記命令cout顯示true和false,而不是1和0 -
for (int i = 0; i < 5; ++i)
這種聲明語句表達式只有在C++中合法,在C中是非法的(須寫成for (i = 0; i < 5; ++i)
) -
有些較老的C++實現遵循以前的規則,對於循環
for (int i = 0; i < 5; ++i)
,將把i視爲是在循環之前聲明的,因此在循環結束後,i仍可用 -
測試表達式中,檢測不等(>、<等等)通常要比檢測相等好
-
++與- - : 以下這條語句在不同的系統上將生成不同的結果:
x = 2 * x++ * (3 - ++x);
,對此,C++沒有定義正確的行爲 -
對於針對類定義的運算符,在循環的更新表達式中,前綴版本
++i
通常會比後綴版本i++
快一些。對於內置類型和當代編譯器則基本沒啥差別 -
前綴遞增、前綴遞減和解除引用運算符的優先級相同,以從右到左的方式進行結合。後綴遞增和後綴遞減的優先級相同,但比前綴運算符的優先級高,這兩個運算符以從左到右的方式進行結合
對此我寫了一個小程序來探討這種單目運算符的優先級:#include<iostream> using namespace std; int main(){ int x[5]{1,5,8,20,115}; int* pt; pt=x+1; int ans= ++*pt++; //ans= 6 *pt= 8 //int ans= *(++pt)++; //ans= 8 *pt= 20 //int ans = (*++pt)++; //ans= 8 *pt= 9 //int ans = *++pt++; //INVALID int y=5; cout<<"ans= "<<ans<<endl; cout<<"*pt= "<<*pt<<endl; return 0; }
-
逗號的作用:①逗號運算符:合併兩個表達式爲一個,如
++j, --i;
②逗號分隔:int i, j;
逗號表達式的值爲第二部分的值,且作爲運算符時優先級最低 -
在循環類聲明簡單變量通常會比在循環前聲明該變量的速度要慢,因爲如果在循環內聲明,該變量在每輪循環都會被分配和釋放
-
for循環的幾種寫法:①
for (int i=0, j=5; ;)
②int i, j; for (i=0,j=5; ;)
③for (; ;++i, --j)
-
C-風格字符串不能用==判斷字符串相等(須用strcmp()進行比較),因爲沒有相關的運算符重載,但string類型有,如
string word; word != "mate";
表達式要求:至少有一個操作數爲string對象,另一個操作數可以是string對象,也可以是C風格字符串 -
for循環中省略測試條件時,將認爲條件爲true
-
用#define需謹慎,最好用typedef定義類型別名。以下pb是float類型而非float*類型
#define FLOAT_POINTER float * FLOAT_POINTER pa, pb; // not expected FLOAT_POINTER pa, *pb; //typedef float* FLOAT_POINTER; // GREAT MEANS
-
基於範圍的for循環(C++11):①
for (double x : prices)
;②for (double &x : prices)
;③for (int x : {4, 3, 9, 6})
; -
cin讀取char值時,與讀取其他類型一樣,會忽視空格與換行符
以下代碼中主要討論幾種cin.get()的重載#include<iostream> #include<string> using namespace std; int main(){ const int ArrSize = 20; char name1[ArrSize]; char name2[ArrSize]; char name3[ArrSize]; /* //Method1 cin.get(name1,ArrSize).get(); cin.get(name2,ArrSize).get(); cin.get(name3,ArrSize).get(); */ //Method2 cin.get(name1,ArrSize); cin.get(name2,ArrSize); cin.get(name3,ArrSize); cout<<"name1= "<<name1<<endl; cout<<"name2= "<<name2<<endl; cout<<"name3= "<<name3<<endl; return 0; }
-
cin.get(char)
的返回值爲cin對象,然而istream類提供了一個可將istream對象(如cin)轉換爲bool值的函數,如果最後一次讀取成功了,則轉換得到的bool值爲true,否則爲false -
文件尾的幾種判斷:①
while (cin.fail() == false) or while (cin.eof() == false)
fail()和eof()都是事後報告結果②while (cin)
比前者更通用,因爲它可以檢測到其它失敗原因,如磁盤故障;③while (cin.get(ch))
測試表達式中同時實現了三條指導原則(確定結束條件、對條件初始化以及更新條件);④while (ch != EOF)
;⑤while ((ch = cin.get()) != EOF)
,注意括號一個不能少 -
模擬EOF條件:Ctrl+Z和回車(不同系統可能對是否回車要求不同),在有些系統中,Ctrl+Z實際將結束輸入輸出,而cin.clear()將無法恢復輸入和輸出
-
cout.put(ch);
由於put()有三種原型,對應參數分別爲char
、signed char
和unsigned char
,因此如果傳入的參數爲int,須進行強制類型轉換,如cout.put(char(ch));
-
在有些系統中,char類型是無符號的,因此char變量不可能爲EOF值(-1)。出於此原因,如果使用cin.get()並測試EOF,則必須將返回值賦給int型變量,而不是char變量(見第18條序號⑤);另外,如果聲明的是int變量而非char變量,需要顯示字符時需要進行強制類型轉換
-
cin.get()與cin.get(ch)的區別見下表
屬 性 | cin.get(ch) | ch = cin.get() |
傳遞輸入字符的方式 | 賦給參數ch | 將函數返回值賦給ch |
用於字符輸入時函數的返回值 | istream對象(執行bool轉換後返回值爲true) | int類型的字符編碼 |
到達EOF時函數的返回值 | istream對象(執行bool轉換後返回值爲true) | EOF |