C++ Primer(第五版)讀書筆記 & 習題解答 --- Chapter 1
Chapter 1.1
1. 每個C++程序都必須有且只能有一個main函數,main函數的返回類型必須是int。操作系統通過調用main函數來運行C++程序。
2. 一個函數的定義包含四部分:返回類型、函數名、形參列表以及函數體。
3. 當return語句包含一個值時,此返回值的類型必須與函數的返回類型相兼容。
4. 類型是程序設計最基本的概念之一。一種類型不僅定義了數據元素的內容,還定義了這類數據上可以進行的運算。
Chapter 1.2
1. C++包含了一個全面的標准庫,標准庫就是一個類型和函數的集合,每個C++編譯器都必須支持。
2. 標准庫中包含了iostream庫,用來提供IO機制。iostream庫包含了兩個基礎類型istream和ostream,分別表示輸入流和輸出流。一個流就是一個字符序列,術語“流”想要表達的是,隨著時間的推移,字符是順序生成或消耗的。
3. 標准庫定義了4個IO對象:1. cin,一個istream類型的對象,也被稱為標准輸入,用來處理輸入 2. cout,一個ostream類型的對象,也被稱為標准輸出,用來處理輸出 3. cerr,一個ostream類型的對象,也被稱為標准錯誤,通常寫入到與標准輸出相同的設備,用來輸出錯誤信息或其他不屬於程序正常邏輯的輸出內容。默認情況下,寫到cerr的數據是不緩沖的 4. clog,一個ostream類型的對象,用來報告程序的執行信息。默認情況下,寫到clog的數據是被緩沖的。
4. #include指令和頭文件的名字必須寫在同一行中。
5. 輸出(<<)運算符的計算結果就是其左側運算對象。代碼:
std::cout << "Enter two numbers:" << std::endl;
使用了輸出運算符兩次。因為輸出運算符的結果是其左側運算對象,所以第一個運算符的結果成為了第二個運算符的左側
運算對象。因此,我們的代碼等價於:
// 表達式 std::cout << "Enter two numbers:" 的運算結果是std::cout
std::cout << "Enter two numbers:";
std::cout << std::endl;
6. 輸入(>>)運算符與輸出運算符類似,返回其左側運算對象作為其計算結果。因此,代碼:
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
等價於:
// 表達式 std::cin >> v1 的運算結果是std::cin
int v1 = 0, v2 = 0;
std::cin >> v1;
std::cin >> v2;
7. IO設備通常將輸入(或輸出)數據保存在一個緩沖區中。
8. std::endl是一個被稱為操縱符的特殊值。寫入std::endl的效果是結束當前行,並將與設備關聯的緩沖區中的內容刷到設備中。
9. 標准庫定義的所有名字都在命名空間std中。
Chapter 1.3
1. 編譯器會忽略注釋,因此注釋對程序的行為或性能不會有任何影響。
2. C++中有兩種注釋:單行注釋和界定符對注釋。
單行注釋以雙斜線(//)開始,以換行符結束。這種注釋可以包含任何文本,包括額外的雙斜線。
界定符對注釋以“/*”開始,以“*/”結束,可以包含除“*/”外的任意內容。
3. 界定符對注釋不能嵌套。下面的代碼中嵌套使用界定符對注釋就會產生錯誤:
int main()
{
/* /* 注釋1 */ 注釋2 */
// "注釋2 */" 會被當做源碼
return 0;
}
Chapter 1.4
1. 所謂語句塊,就是用花括號包圍的零條或多條語句的序列。語句塊也是語句的一種,在任何要求使用語句的地方都可以使用語句塊。
2. while語句的形式為:
while ( condition ) // 所謂condition就是一個產生真或假的結果的表達式
statement
while語句的執行過程是交替地檢測condition和執行關聯的語句statement,直至condition為假時停止。
3.
for ( int val = 1; val <= 10; ++val )
statement;
上述代碼使用了for語句。每個for語句都包含兩部分:循環頭和循環體。循環頭控制循環體的執行次數,它由三部分組成:初始化語句、循環條件以及表達式。在上述代碼中,初始化語句為“int val = 1”,初始化語句只在for語句入口處執行一次。在上述代碼中,循環條件為“val <= 10”,循環體每次執行前都會先檢查循環條件,只要循環條件為真,循環體就會被執行。在上述代碼中,表達式為“++val”,表達式在循環體之後執行,執行完表達式後,for語句就會重新檢測循環條件。
4. 當使用一個istream對象作為條件時,其效果是檢測流的狀態。如果流是有效的,則條件為真。當遇到文件結束符或遇到一個無效輸入時,istream對象的狀態會變為無效。處於無效狀態的istream對象會使條件變為假。
5. 當用鍵盤向程序輸入數據時,對於如何指定文件結束,不同操作系統有不同的約定。在Windows系統中,輸入文件結束符的方法是Ctrl + Z。在Unix系統中,包括Mac OS X系統中,輸入文件結束符的方法是Ctrl + D。
Chapter 1.5
1. 每個類實際上都定義了一個新的類型,其類型名就是類名。
2. 大多數操作系統支持文件重定向,這種機制允許我們將標准輸入和標准輸出與命名文件關聯起來:
$ addItems <infile >outfile
假定$是操作系統提示符,應用程序為addItems.exe,則上述命令會從一個名為infile的文件讀取銷售記錄,並將輸出結果寫入到一個名為outfile的文件中,兩個文件都位於當前目錄中。
Exercises Section 1.2
Q_1. Write a program to print Hello, World on the standard output.
A_1.
復制代碼
#include <iostream>
int main()
{
std::cout << "Hello, World" << std::endl;
return 0;
}
復制代碼
Q_2. Our program used the addition operator, +, to add two numbers. Write a program that uses the multiplication operator, *, to print the product instead.
A_2.
復制代碼
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
std::cout << "The product of " << v1 << " and " << v2 << " is " << v1 * v2 << std::endl;
return 0;
}
復制代碼
Q_3. We wrote the output in one large statement. Rewrite the program to use a separate statement to print each operand.
A_3.
復制代碼
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
std::cout << "The sum of ";
std::cout << v1;
std::cout << " and ";
std::cout << v2;
std::cout << " is ";
std::cout << v1 + v2;
std::cout << std::endl;
return 0;
}
復制代碼
Q_4. Explain whether the following program fragment is legal.
std::cout << "The sum of " << v1;
<< " and " << v2;
<< " is " << v1 + v2 << std::endl;
If the program is legal, what does it do? If the program is not legal, why not? How would you fix it?
A_4. 這個程序是非法的,v1後的分號表示了一條語句的結束,所以程序會認為“<< " and " << v2;”是一條獨立的語句,而這條語句缺少了左側運算對象。同理,“<< " is " << v1 + v2 << std::endl;”也缺少了左側運算對象。
修正如下:
std::cout << "The sum of " << v1 // 去除分號
<< " and " << v2 // 去除分號
<< " is " << v1 + v2 << std::endl;
Exercises Section 1.3
Q_1. Indicate which, if any, of the following output statements are legal:
std::cout << "/*";
std::cout << "*/";
std::cout << /* "*/" */;
std::cout << /* "*/" /* "/*" */;
After you've predicted what will happen, test your answers by compiling a program with each of these statements. Correct any errors you encounter.
A_1.
復制代碼
std::cout << "/*"; // 合法
std::cout << "*/"; // 合法
std::cout << /* "*/" */;
// 非法,修正為:
std::cout << /* "*/" */";
std::cout << /* "*/" /* "/*" */; // 合法
復制代碼
Exercises Section 1.4.1
Q_1. Write a program that uses a while to sum the numbers from 50 to 100
A_1.
復制代碼
#include <iostream>
int main()
{
int sum = 0, val = 50;
while ( val <= 100 )
{
sum += val;
++val;
}
std::cout << "Sum of 50 to 100 inclusive is " << sum << std::endl;
return 0;
}
復制代碼
Q_2. In addition to the ++ operator that adds 1 to its operand, there is a decrement operator (--) that subtracts 1. Use the decrement operator to write a while that prints the numbers from ten down to zero.
A_2.
復制代碼
#include <iostream>
int main()
{
int val = 10;
while ( val >= 0 )
{
std::cout << val << std::endl;
--val;
}
return 0;
}
復制代碼
Q_3. Write a program that prompts the user for two integers. Print each number in the range specified by those two integers.
A_3.
復制代碼
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
while ( v1 <= v2 )
{
std::cout << v1 << std::endl;
++v1;
}
return 0;
}
復制代碼
Exercises Section 1.4.2
Q_1. What does the following for loop do? What is the final value of sum?
int sum = 0;
for (int i = -100; i <= 100; ++i)
sum += i;
A_1. 上述代碼的功能是計算-100到100的和,最終sum的結果是0。
Q_2. Rewrite the exercises from § 1.4.1 (p. 13) using for loops
A_2.
復制代碼
#include <iostream>
int main()
{
int sum = 0;
for ( int val = 50; val <= 100; ++val )
{
sum += val;
}
std::cout << "Sum of 50 to 100 inclusive is " << sum << std::endl;
return 0;
}
復制代碼
復制代碼
#include <iostream>
int main()
{
for ( int val = 10; val >= 0; --val )
{
std::cout << val << std::endl;
}
return 0;
}
復制代碼
復制代碼
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
for ( ; v1 <= v2; ++v1 )
{
std::cout << v1 << std::endl;
}
return 0;
}
復制代碼
Exercises Section 1.4.3
Q_1. Write your own version of a program that prints the sum of a set of integers read from cin.
A_1.
復制代碼
#include <iostream>
int main()
{
int sum = 0;
for ( int val; std::cin >> val; )
{
sum += val;
}
std::cout << "Sum is: " << sum << std::endl;
return 0;
}
復制代碼
Exercises Section 1.4.4
Q_1. Revise the program you wrote for the exercises in § 1.4.1 (p. 13) that printed a range of numbers so that it handles input in which the first number is smaller than the second.
A_1.
復制代碼
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
if ( v1 > v2 )
{
// 如果v1大於v2,就進行交換
int temp = v1;
v1 = v2;
v2 = temp;
}
while ( v1 <= v2 )
{
std::cout << v1 << std::endl;
++v1;
}
return 0;
}
復制代碼
Exercises Section 1.5.1
Q_1. http://www.informit.com/title/032174113 contains a copy of Sales_item.h in the Chapter 1 code directory. Copy that file to your working directory. Use it to write a program that reads a set of book sales transactions, writing each transaction to the standard output.
A_1.
復制代碼
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item book;
while ( std::cin >> book )
{
std::cout << book << std::endl;
}
return 0;
}
復制代碼
Q_2. Write a program that reads two Sales_item objects that have the same ISBN and produces their sum.
A_2.
復制代碼
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item item1, item2;
std::cin >> item1 >> item2;
std::cout << item1 + item2 << std::endl;
return 0;
}
復制代碼
Q_3. Write a program that reads several transactions for the same ISBN. Write the sum of all the transactions that were read.
A_3.
復制代碼
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item sum, val;
// 讀取第一筆交易
std::cin >> sum;
// 累加所有交易
while ( std::cin >> val )
{
sum = sum + val;
}
std::cout << sum << std::endl;
return 0;
}
復制代碼
Exercises Section 1.5.2
Q_1. Write a program that reads several transactions and counts how many transactions occur for each ISBN.
A_1.
復制代碼
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item lastItem;
if ( std::cin >> lastItem )
{
int count = 1;
Sales_item curItem;
while ( std::cin >> curItem )
{
if ( lastItem.isbn() == curItem.isbn() )
{
++count;
}
else
{
std::cout << lastItem.isbn() << " occurs " << count;
lastItem = curItem;
count = 1;
}
}
std::cout << lastItem.isbn() << " occurs " << count;
}
return 0;