C++ Primer 第一章 學習筆記及習題答案
知識點
函式定義
· 一個程式包含一個或多個函式(有且只有一個main函式);一個函式定義包含四部分:返回型別、函式名、形參列表、函式體。如下程式碼為一個最簡單的main函式,int為其返回型別,main為函式名,括號()括起來的為形參列表(可為空),花括號{}括起來的內容為函式體。
int main()
{
return 0;
}
輸入輸出
· C++使用標準庫來提供IO機制,通常用到iostream庫,需要在程式首部引入標頭檔案#include <iostream>
,
· endl為操縱符,效果:結束當行,將與裝置關聯的緩衝區中內容刷到裝置中,保證目前程式所產生的輸出都真正寫入到輸出流中。
Tips:需要通過名稱空間才可使用標準庫中的一個名字,即必須顯式說明我們想使用來自名稱空間std中的名字。有兩種實現方式:
1 使用作用域運算子::
using namespace std;
,使用後即可不用作用域運算子進行字首,直接寫cin、cout即可。
註釋
· 單行註釋:// · 多行註釋:/* */ Tips:多行註釋不可巢狀,在除錯時儘量使用單行註釋註釋整個程式碼段的每一行。 VS 2017中多行註釋方法:1 選定程式碼段;2 按下CTRL+K;3 按下CTRL+C。 取消多行註釋方法:1 選定程式碼段;2 按下CTRL+K;3 按下CTRL+U。
while和for控制流
while
· while語句形式:
while (condition) statement
while語句持續交替檢測condition和執行statement,直到condition為假為止。 while可用來讀取數量不定的輸入資料,程式碼如下:
int val=0;
while(std::cin>>val) //一直輸入,直到遇到無效輸入就退出迴圈
for
for(init-statement;condition;expression)
example:for(int i=0;i<10;++i)
例子中總體執行過程如下: 1 建立變數i,初始化為0; 2 檢測i是否小於10,如果滿足條件,則進入for迴圈體,如果不滿足條件,則推出迴圈體; 3 將i的值加1; 4 重複步驟2,若滿足條件這繼續執行剩餘步驟直到步驟2不滿足條件退出迴圈。
類(看完後續補充)
· C++中,通過一個類來定義自己的資料結構。 · 類的作者定義了類物件可以執行的所有動作。
練習題
1.1節練習
練習1.1:查閱你使用的編譯器文件,確定它所使用的檔案命名約定。編譯並執行第二頁的main程式。 執行結果如下: 練習1.2:改寫程式,讓他返回-1。返回值-1通常被當作程式錯誤的標識。重新編譯並執行你的程式,觀察你的系統如何處理main返回的錯誤標識。 執行結果如下: 總結:在大多數系統中,main的返回值被用來指示狀態。返回0表明成功,非0的返回值通常用來指出錯誤型別。
1.2節練習
練習1.3:編寫程式,在標準輸出上列印Hello,World。
int main()
{
std::cout << "Hello, world!" << endl;
return 0;
}
練習1.4:我們的程式使用加法運算子+來將兩個數相加。編寫程式使用乘法運算子*,來列印兩個數的積。
int main()
{
int a, b;
std::cout << "輸入兩個整數:" ;
std::cin >> a >> b;
int sum = a * b;
std::cout << "它們的乘積為:"<< sum << std::endl;
return 0;
}
練習1.5:我們將所有輸出操作放在一條很長的語句中。重寫程式,將每個運算物件的列印操作放在一條獨立的語句中。
std::cout<<"abc"<<"xyz"<<std::endl;
等價於如下程式碼段:
std::cout<<"abc";
std::cout<<"xyz";
std::cout<<endl;
練習1.6:解釋下面程式片段是否合法。
std::cout << "The sum of "<< v1;
<< " and " << v2;
<< " is " << v1 + v2 << std::endl;
不合法,輸出運算子<< 必須接受兩個運算物件 ,左側的運算物件必須是一個ostream物件,右側的運算物件是要列印的值。題中第2/3行程式碼的輸出運算子左側為空,故不合法。
1.3節練習
練習1.7:編譯一個包含不正確的巢狀註釋的程式,觀察編譯器返回的錯誤資訊。
int main()
{
std::cout <</* /* */*/<<endl;
return 0;
}
執行結果: 練習1.8:指出下列哪些輸出語句是合法的(如果有的話):
std::cout << " /* ";
std::cout << " */ ";
std::cout << /* "*/" */;
std::cout << /* "*/" /* "/*" */;
1、2合法,3、4不合法。 3、4發生了多行註釋的巢狀使用。
1.4節練習
1.4.1節練習
練習1.9:編寫程式,使用while迴圈將50到100的整數相加。
int main()
{
int i = 50, sum = 0;
while (i <= 100) {
sum += i;
++i;
}
std::cout << "50到100依次相加的值為:" << sum << endl;
return 0;
}
練習1.10:除了++運算子將運算物件的值增加1之外,還有一個遞減運算子(–)實現將值減少1。編寫程式,使用遞減運算子在迴圈中按遞減順序打印出10到0之間的整數。
int main()
{
int i = 10;
std::cout << "從10到0依次為:";
while (i >= 0) {
std::cout <<i <<" ";
--i;
}
return 0;
練習1.11:編寫程式,提示使用者輸入兩個整數,打印出這兩個整數所指定的範圍內的所有整數。
int main()
{
int a, b;
std::cout << "請輸入兩個數:";
std::cin >> a >> b;
std::cout << "這兩個整數範圍內的數為:";
if (a <= b) {
while (a <= b) {
std::cout << a << " ";
++a;
}
}
else {
while (a >= b) {
std::cout << a << " ";
--a;
}
}
return 0;
}
1.4.2節練習
練習1.12:下面的for迴圈完成了什麼功能?sum的終值是多少?
int sum=0;
for(int i=-100; i<=100; ++i)
sum += i;
for迴圈實現了從-100到100的累加功能,sum的終值為0。
練習1.13:使用for迴圈重做1.4.1節中的所有練習。
//累加50到100的整數
int main()
{
int sum = 0;
for (int i = 50; i <= 100; i++)
sum += i;
std::cout <<"50到100的累加和為:"<< sum;
return 0;
}
//遞減列印10到0之間整數
int main()
{
std::cout << "遞減輸出依次為:";
for (int i = 10; i >= 0; --i)
std::cout<<i << " ";
return 0;
}
//輸入兩個整數,打印出這兩個整數所指定的範圍內的所有整數
int main()
{
std::cout << "請輸入兩個整數:" ;
int a=0, b=0;
std::cin >> a >> b;
std::cout << "這兩個整數範圍內的數為:";
if (a <=b) {
for (int i = a; i <= b; ++i)
std::cout << i << " ";
}
else {
for (int i = a; i >= b; --i)
std::cout << i << " ";
}
return 0;
}
練習1.14:對比for迴圈和while迴圈,兩種形式的優缺點各是什麼?
while迴圈 | for迴圈 |
---|---|
需求未明確迴圈次數 | 需求明確迴圈次數 |
使用迴圈後還想訪問迴圈語句去控制該變數 | 區域性變數在棧記憶體中存在,當for迴圈結束變數會及時釋放,不浪費空間 |
練習1.15:編寫程式,包含第14頁“再探編譯”中討論的常見錯誤。熟悉編譯器生成的錯誤資訊。 自己看書,略。
1.4.3節練習
練習1.16:編寫程式,從cin讀取一組數,輸出其和。
int main()
{
int sum = 0, val = 0;
std::cout << "請輸入一組數:";
while (std::cin >> val)
sum += val;
std::cout <<"輸入的數和為:"<< sum << endl;
return 0;
}
1.4.4節練習
1.17-1.18程式碼:
int main()
{
int currVal = 0, val = 0;
if (std:: cin >> currVal) {
int cnt = 1;
while (std::cin >> val) {
if (val == currVal)
++cnt;
else {
std::cout << currVal << " occurs " << cnt << " times" << endl;
currVal = val;
cnt = 1;
}
}
std::cout << currVal << " occurs " << cnt << " times" << endl;
}
return 0;
}
練習1.17:如果輸入的所有值都是相等的,本節的程式會輸出什麼?如果沒有重複值,輸出又會是怎樣的? 所有值都相等的情況,程式輸出該值出現次數;沒有重複值的情況,輸出每一個值及各出現一次。 練習1.18:編譯並執行本節的程式,給它輸入全都相等的值。再次執行程式,輸入沒有重複的值。 所有值相等,輸出結果:
42 42 42 42 endl
42 occurs 4 times
沒有重複值,輸出結果:
40 41 42 43 endl
40 occurs 1 times
41 occurs 1 times
42 occurs 1 times
43 occurs 1 times
練習1.19:修改你為1.4.1節練習1.10所編寫的程式(列印一個範圍內的數),使其能處理使用者輸入的第一個數比第二個數小的情況。 之前程式碼已經考慮過這個情況,見上。
1.5節練習
1.5.1節練習
練習1.20:在網站http://www.informit.com/title/0321714113上,第1章的程式碼目錄中包含了標頭檔案Sales_item.h。將它拷貝到你自己的工作目錄中。用它編寫一個程式,讀取一組書籍銷售記錄,將每條記錄列印到標準輸出上。
//需先下載標頭檔案,並在專案中匯入
int main()
{
Sales_item book;
cout << "請輸入一條書籍銷售記錄:";
std::cin >> book;
std::cout <<"記錄如下:"<< book << endl;
return 0;
}
練習1.21:編寫程式,讀取兩個ISBN相同的Sales_item物件,輸出他們的和。
int main()
{
Sales_item item1, item2;
cout << "請輸入兩條ISBN相同的記錄:";
std::cin >> item1 >> item2;
std::cout <<"這兩條記錄的和為:"<< item1 + item2 << endl;
return 0;
}
練習1.22:編寫程式,讀取多個具有相同ISBN的銷售記錄,輸出所有記錄的和。
//要先輸入一個值,再迴圈輸入
int main()
{
Sales_item item, sum;
if (std::cin >> sum) {
while (std::cin >> item)
sum += item;
}
std::cout << sum << endl;
return 0;
}
1.5.2節練習
練習1.23:編寫程式,讀取多條銷售記錄,並統計每個ISBN(每本書)有幾條銷售記錄。
//與練習1.17-1.18類似,要先輸入一個值,再迴圈輸入
int main()
{
Sales_item currVal, val;
int num = 1;
std::cout << "請輸入多條相同ISBN的銷售記錄:";
if (cin >> val) {
while (cin >> currVal) {
if (val.isbn() == currVal.isbn()) {
++num;
}
else {
cout << val.isbn() << "共有" << num << "條銷售記錄" << endl;
num = 1;
val = currVal;
}
}
cout << val.isbn() << "共有" << num << "條銷售記錄" << endl;
}
return 0;
}
練習1.24:輸入表示多個ISBN的多條銷售記錄來測試上一個程式,每個ISBN的記錄應該聚在一起。 用練習1.23程式碼測試即可。
1.6節練習
練習1.25:藉助網站上的Sales_item.h標頭檔案,編譯並執行本節所給出的書店程式。 (還未做)