標籤:
*****C++ Primer 第五版第1章學習筆記*****
*****實驗代碼在Red Hat 6.6或VS 2013中調試*****
*****文章內容依據當前知識撰寫,存在認識的局限性*****
1.1 編寫一個簡單的C++程式
函數:依據我個人理解,C/C++的函數是一個能夠完成一個功能的模組。
完整函數的組成:
①傳回型別:不一定有傳回值,故不一定有傳回型別
②函數名:根據名字標識完成特定功能的模組,必須存在
③形參列表:可能沒有參數傳入,不一定存在
④函數體:一個完整的函數應該是有函數體的,裡麵包含要實現的功能。
下面為一個完整函數的例子:
int main(){return 0;}
1.1.1 編譯、運行程式
正如書上所說,先將精力集中於C++語言本身,而後再來學習IDE,此處略過。
1.1節練習
練習 1.2:改寫程式,讓它返回-1。傳回值-1 通常被當作程式錯誤的標識。重新編譯並運行你的程式,觀察你的系統如何處理main 返回的錯誤標識。
解答:在Red Hat下沒辦法成功編譯,一直報這樣的錯誤:
在VS 2013中可以編譯成功,但是與return 0是一模一樣的,沒有觀察到效果。
1.2 初識輸入輸出
輸入和輸出並不是C++語言中的正式組成成分。C和C++本身都沒有為輸入和輸出提供專門的語句結構。輸入輸出不是由C++本身定義的,而是在編譯系統提供的I/O庫中定義的。
C++標準輸入輸出定義了4個IO,分別為:CIN(標準輸入)、COUT(標準輸出)、CERR(標準錯誤)、CLOG,這四個是自動與當前程式開啟關聯的。
標準輸入輸出存在緩衝和非緩衝的概念,但印象中標準錯誤是非緩衝的,一旦出現錯誤,就立馬輸出錯誤。
練習 1.3:編寫程式,在標準輸出上列印Hello, World。
解答:
int main(){std::cout << "Hello,World." << std::endl;return 0;}
練習1.4:我們的程式使用加法運算子+來將兩個數相加。編寫程式使用乘法運算子*,來列印兩個數的積。
解答:
int main(){int v1 = 0, v2 = 0;std::cout << "input two numbers:" << std::endl;std::cin >> v1 >> v2;std::cout << "the product of " << v1 << " and " << v2 << " is " << v1*v2 << std::endl;return 0;}
練習 1.5:我們將所有輸出操作放在一條很長的語句中。重寫程式,將每個運算對象的列印操作放在一條獨立的語句中。
解答:
#include<iostream>int main(){int v1 = 0, v2 = 0;std::cout << "input two numbers:" << std::endl;std::cin >> v1 >> v2;std::cout << "the product of ";std::cout << v1;std::cout << " and ";std::cout << v2;std::cout << " is ";std::cout << v1*v2;std::cout << std::endl;return 0;}
練習 1.6:解釋下面程式片段是否合法。
std::cout << "The sum of " << v1;<< " and " << v2;<< " is " << v1 + v2 << std::endl;
如果程式是合法的,它輸出什嗎?如果程式不合法,原因何在?應該如何修正?
解答:
std::cout << "The sum of " << v1; //合法,假定v1=1,則輸出The sum of 1
<< " and " << v2;//不合法,因為沒有標準輸出IO,應修正為std::cout << " and " << v2;
<< " is " << v1 + v2 << std::endl; ////不合法,原因同第二個語句,沒有標準輸出IO,應修正為 std::cout << " is " << v1 + v2 << std::endl;
1.3 注釋簡介
C++有2種注釋風格,一種單行雙斜杠注釋,如 //這是一個注釋
另外一直是多行界定符注釋,如/*注釋內容*/,這種注釋不能相互嵌套,比如注釋/* 第一層注釋 /* 第二層注釋 */ 第一層這是 */,這種情況下從第一個界定符到第三個界定符視為注釋,最後一個*/則視為不能識別的代碼。
1.3節練習
練習1.7:編譯一個包含 不正確的嵌套注釋的程式,觀察編譯器返回的錯誤資訊。
int main(){std::cout << "test of comments!";/* /* test */ */return 0;}
VS 2013報錯:1>------ Build started: Project: return, Configuration: Debug Win32 ------1> return.cpp1>c:\users\pluse\documents\visual studio 2013\projects\return\return\return.cpp(4): warning C4138: ‘*/‘ found outside of comment1>c:\users\pluse\documents\visual studio 2013\projects\return\return\return.cpp(4): error C2059: syntax error : ‘/‘========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Red Hat報錯:1.7.cpp: In function ‘int main()’:1.7.cpp:4: error: expected primary-expression before ‘/’ token1.7.cpp:5: error: expected primary-expression before ‘return’1.7.cpp:5: error: expected ‘;’ before ‘return’
練習1.8:指出下列哪些輸出語句是合法的(如果有的話):
std::cout << "/*";std::cout << "*/";std::cout << /* "*/" */;std::cout << /* "*/" /* "/*" */;
預測編譯這些語句會產生什麼樣的結果,實際編譯這些語句來驗證你的答案(編寫一個小程式,每次將上述一條語句作為其主體),改正每個編譯錯誤。
解答:
雙引號裡麵包含的內容是直接輸出的,不做注釋用,因此前3個文法都是正確的,除了最後一個錯誤。應該修改為:
std::cout << /* "*/" /* /*";
1.4 控制流程1.4.1 While語句While迴圈的格式為:
while(condition) //注意括弧statement
練習 1.9:編寫程式,使用while 迴圈將50 到100 的整數相加。解答:
#include<iostream>int main(){int val = 50, sum = 0;while (val <= 100){sum += val;val++;}std::cout << "Sum of 50 to 100 inclusive is " << sum << std::endl;return 0;}
練習 1.10:除了++運算子將運算對象的值增加1 之外,還有一個遞減運算子實現將值減少1。編寫程式,使用遞減運算子在迴圈中按遞減順序列印出10 到0 之間的整數。解答:
#include<iostream>int main(){int val = 10;while (val >=0){std::cout << val<<" ";val--;}std::cout << std::endl;return 0;} 練習 1.11:編寫程式,提示使用者輸入兩個整數,列印出這兩個整數所指定的範圍內的所有整數。
解答:
#include<iostream> //目前還未學習其他的迴圈和判定,因此僅使用while來實現int main(){int a,b;std::cout << "input two numbers:";std::cin >> a >> b;while (a<=b){std::cout << a << " ";a++;}while (a > b){std::cout << b << " ";b++;}std::cout << std::endl;return 0;}
1.4.2 for 語句for語句的形式需要注意
for(INITIALIZATION;CONDITION;INCREMENT) //注意分號!statement;
練習 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 節中的所有練習(第13 頁)。解答:略
練習 1.14:對比for 迴圈和while 迴圈,兩種形式的優缺點各是什嗎?解答:在我看來是2種不同形式的迴圈,沒有太大差別,引用搜尋出來的答案:“在for迴圈中,迴圈控制變數的初始化和修改都放在語句頭部分,形式較簡潔,且特別適用於迴圈次數已知的情況。在while迴圈中,迴圈控制變數的初始化一般放在while語句之前,迴圈控制變數的修改一般放在迴圈體中,形式上不如for語句簡潔,但它比較適用於迴圈次數不易預知的情況(用某一條件控制迴圈)。兩種形式各有優點,但它們在功能上是等價的,可以相互轉換。”
練習 1.15:編寫程式,包含第16 頁“再探編譯”中討論的常見錯誤。熟悉編譯器產生的錯誤資訊。解答:略 1.4.3 讀取數量不定的輸入資料在這一部分學習到while迴圈可以使用這種格式:while (std::cin >> value),這個在C語言中沒有見過,但是有類似的。 練習 1.16:編寫程式,從cin 讀取一組數,輸出其和。
#include<iostream> //書上的程式並不能很好的工作,沒有提供結束的方法int main(){int sum = 0, value = 0;std::cout << "enter q to quit:"; //輸入字母q來退出,實際上,任何字母都能退出,這是因為value是一個int類型,輸入的q屬於char類型,while (std::cin >> value) //因此std::cin >> value會返回false從而結束迴圈sum += value;std::cout << "Sum is: " << sum << std::endl; return 0;}
1.4.4 if語句if語句形式:
if(expression)</span>//注意if後面的括弧!!statement;
練習1.17:如果輸入的所有值都是相等的,本節的程式會輸出什嗎?如果沒有重複值,輸出又會是怎樣的?解答:如果輸入的所有值都是相等的,程式會輸出輸入的值連續出現了多少次。如果沒有重複值,輸出會輸出之前的值連續出現了1次。 練習1.18:編譯並運行本節的程式,給它輸入全都相等的值。再次運行程式,輸入沒有重複的值。解答:略 練習1.19:修改你為1.4.1節練習1.10(第13頁)所編寫的程式(列印一個範圍內的數),使其能處理使用者輸入的第一個數比第二個數小的情況。解答:推測題目要求修改的程式應該是1.4.1節練習1.11,1.11的答案已能實現。 1.5類簡介終於來到“類”的學習了!看到課本中類的介紹,我第一時間想到的就是剛剛學完的C裡面的結構,類和結構很像,是自訂的一直類型,但是差別很大。再看類的介紹,又想起了C語言裡面的ADT,ADT與類很像,但是也有很大的差別。第一,在非物件導向環境(如C與Fortran)中只能使用ADT,處理多個資料執行個體的時候,需要手動設定,要為ADT添加一些用來建立和刪除執行個體的服務作業,還需要重新設計ADT的其他服務作業以能夠支援多個執行個體。 類就不必了。 對類的初步理解是類是為C++定義的一種外置資料類型,一種資料類型確定的時候也就相應的確定了類型的一個屬性集和一個操作集。比如,int類型的屬性是它表示一個整數值,因此它擁有整數的屬性。它允許的算術操作是改變一個int數的符號、兩個int數相加、兩個int數相減、兩個int數相乘、兩個int數相除,以及一個int數對另一個模數。在聲明一個變數為int型時,您的意思是這些操作並且只有這些操作可以對其起作用。【這段話來自C Primer Plus】 練習 1.20:在網站http://www.informit.com/title/0321714113 上,第1 章的代碼目錄中包含了標頭檔Sales_item.h。將它拷貝到你自己的工作目錄中。用它編寫一個程式,讀取一組書籍銷售記錄,將每條記錄列印到標準輸出上。解答:該小節的實驗需要使用作者的類標頭檔,該書代碼目錄是:http://ptgmedia.pearsoncmg.com/images/9780321714114/downloads/GCC_4_7_0.zip,下載後解壓後可以在裡面找到一個“Version_test.h”標頭檔和1檔案夾下“Sales_item.h”標頭檔,將這2個檔案包含在當前程式源碼檔案的目錄下,注意2個檔案都需要,否則編譯時間會報:Cannot open include file: ‘Version_test.h‘: No such file or directory,導致無法完成編譯。此處採用輸入重新導向來完成,過程如下:1.編譯代碼,產生可執行.exe檔案2.開始--運行--Cmd:將產生的.exe檔案拖入命令列視窗中,再將準備好的一組書籍銷售記錄文字檔拖入命令列視窗中,然後斷行符號執行。形式如所示,具體路徑依據個人目錄環境,僅舉例說明。 練習 1.21:編寫程式,讀取兩個ISBN 相同的Sales_item 對象,輸出它們的和。解答:
#include <iostream>#include "Sales_item.h"int main(){Sales_item item1, item2;std::cin >> item1 >> item2;std::cout << item1 + item2 << std::endl; return 0;} 練習 1.22:編寫程式,讀取多個具有相同ISBN 的銷售記錄,輸出所有記錄的和。解答:答案同練習 1.20
C++ Primer 第五版:第1 章