---
# System prepended metadata

title: 第一章 快速入門 練習

---

# 第一章 快速入門 練習

## 練習 1.1
查閱你編譯器的說明文件，找出它所使用的檔案命名慣例。編譯並執行前面的 main 程式

解：
- g++ --std=c++11 ch1.cpp -o main
- ./main

## 練習 1.2
把程式改成回傳 -1。回傳值 -1 經常被用來表示程式執行失敗。重新編譯並再次執行你的程式，看看你的系統如何處理來自 main 的這種錯誤失敗指示器

解：
- 在 ubuntu 下，使用 g++，回傳 -1，./main 沒有發現任何異常
- echo $?，回傳 255

## 練習 1.3
寫一個程式在標準輸出印出 Hello, World

解：
```cpp
#include <iostream>

int main() {
  std::cout << "Hello, World" << std::endl;
  return 0;
}
```

## 練習 1.4
我們的程式用到加法運算子（addition operator）+ 來相加兩個數字。寫一個程式，使用乘法運算子（multiplication operator）* 印出乘積（producy）

解：
```cpp
#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;
}
```

## 練習 1.5
我們將輸出寫為一個大型述句。改寫這個程式，使用分開的述句來印出各個運算元

解：
```cpp
#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 ";
  std::cout << v1;
  std::cout << " and ";
  std::cout << v2;
  std::cout << " is ";
  std::cout << v1 * v2;
  std::cout << std::endl;
}
```

## 練習 1.6
解釋下列程式片段是否合法
```cpp
std::cout << "The sum of " << v1;
    << " and " << v2;
    << " is " << v1 + v2 << std::endl;
```
如果這個程式是合法的，它會做什麼？如果不合法，那是為什麼呢？你會如何修正它？

解：

此程式不合法，有多餘的分號，修改後如下：
```cpp
std::cout << "The sum of " << v1
    << " and " << v2
    << " is " << v1 + v2 << std::endl;
```

## 練習 1.7
編譯錯誤地內嵌了註解的一個程式

解：
```cpp
/* ... /* ... */ ... */
```
錯誤訊息：
```
<source>:1:18: error: expected unqualified-id before '...' token
    1 | /* ... /* ... */ ... */
      |                  ^~~
Compiler returned: 1
```

## 練習 1.8
指出下列輸出述句何者是合法的（如果有的話）：

```cpp
std::cout << "/*";
std::cout << "*/";
std::cout << /* "*/" */;
std::cout << /* "*/" /* "/*" */;
```

預測了會發生什麼事以後，編譯含有上述各個述句的一個程式來驗證你的答案。更正你所遇到的任何錯誤

解：

只有第三句編譯出錯，改成如下即可：
```cpp
std::cout << /* "*/" */";
```
第四句輸出 " /* "。

## 練習 1.9

寫一個程式用 while 將 50 到 100 的數字加總

解：
```cpp
#include <iostream>

int main() {
  int sum = 0, val = 50;
  while (val <= 100) {
    sum += val;
    val += 1;
  }
  std::cout << "Sum of 50 to 100 inclusive is " << sum << std::endl;
}
```

## 練習 1.10
除了會加 1 到其運算元的 ++ 運算子，另外還有一個會減 1 的遞減運算子（--）。使用遞減運算子寫一個 while，印出從十遞減到零的數字

解：

```cpp
#include <iostream>

int main() {
  int val = 10;
  while (val >= 0) {
    std::cout << val << " ";
    val -= 1;
  }
  std::cout << std::endl;
}
```

## 練習 1.11
寫個程式提示使用者輸入兩個整數。印出由這兩個整數所指定的範圍內的每一個數字

解：

```cpp
#include <iostream>

int main() {
  int start = 0, end = 0;
  std::cout << "Please input two num: ";
  std::cin >> start >> end;
  if (start <= end) {
    while (start <= end) {
      std::cout << start << " ";
      ++start;
    }
    std::cout << std::endl;
  } else {
    std::cout << "start should be smaller than end.";
  }
}
```

## 練習 1.12

下列 for 循環迴圈會做什麼呢？sum 的最終值是什麼呢？
```cpp
int sum = 0;
for (int i = -100; i <= 100; ++i) {
  sum += i;
}
```

解：

從 -100 加到 100，sum 的最終值為 0

## 練習 1.13
使用 for 迴圈改寫 1.4.1 的頭兩個練習

解：
```cpp
#include <iostream>

int main() {
  int sum = 0;
  for (int val = 1; val <= 10; val++) sum += val;
  std::cout << "Sum of 1 to 10 inclusive is " << sum << std::endl;
  return 0;
}
```

## 練習 1.14
對照比較使用 for 的迴圈與使用 while 的迴圈。它們各有什麼優缺點呢？

解：

for 迴圈與 while 迴圈之間最主要的差異在於語意問題，當我們的迭代次數已知時，我們通常會使用 for，並在事先不知道迭代次數時使用 while

## 練習 1.15
寫一個程式，其中含有後面含有補充 重訪編譯 中所討論的常見錯誤。讓自己熟悉編譯器產生的那些訊息

解：

編譯器可以檢查出的錯誤有：
- 語法錯誤
- 型別錯誤

## 練習 1.16
寫出你自己的程式，從 cin 讀取一組整數並印出它們的總和

解：

```cpp
#include <iostream>

int main() {
  int sum = 0;
  for (int value = 0; std::cin >> value;) sum += value;
  std::cout << sum << std::endl;
  return 0;
}
```

## 練習 1.17
如果輸入的值全都相同，那麼本節中的程式會發生什麼事呢？如果沒有重複的數字呢？

解：

如果輸入的值全部相同為 n，則會輸出 n 出現了 m 次，如果沒有重複的數字，則每個數字則各出現 1 次

## 練習 1.18
編譯並執行本節的程式，賦予它相同的值作為輸入。給它不同的值，然後再次執行它

解：

全部重複：
```
1 1 1 1 1
1 occurs 5 times
```

沒有重複：
```
1 2 3 4 5
1 occurs 1 times
2 occurs 1 times
3 occurs 1 times
4 occurs 1 times
5 occurs 1 times
```

## 練習 1.19
修改你為 1.4.1 的練習所寫的那個會印出一個範圍的數字的程式，讓它能夠處理第一個數字小於第二個的輸入

解：

```cpp
#include <iostream>

int main() {
  int start = 0, end = 0;
  std::cout << "Please input two num: ";
  std::cin >> start >> end;
  if (start > end) std::swap(start, end);
  while (start <= end) {
    std::cout << start << " ";
    ++start;
  }
  std::cout << std::endl;
}
```

## 練習 1.20
http://www.informit.com/title/032174113 含有 Sales_item.h，位在第 1 章的程式碼目錄中。將那個檔案複製到你的工作目錄。用它來撰寫第一個程式，讀取一組書籍販售紀錄，再將每筆交易紀錄寫到標準輸出

解：

```cpp
#include <iostream>

#include "Sales_item.h"

int main() {
  for (Sales_item item; std::cin >> item; std::cout << item << std::endl)
    ;
  return 0;
}
```

輸入/輸出：
```bash
./main # 執行
0-201-01234-X 3 20.00 # ISBN 數量 單價
0-201-01234-X 3 60 20 # ISBN 數量 總價 單價
0-201-56789-X 2 25.00 # ISBN 數量 單價
0-201-56789-X 2 50 25 # ISBN 數量 總價 單價
```

## 練習 1.21
寫一個程式，讀取兩個具有相同 ISBN 的 Sale_item 物件，並產生它們的總和

解：

```cpp
#include <iostream>

#include "Sales_item.h"

int main() {
  Sales_item item1, item2;
  std::cin >> item1 >> item2;
  if (item1.isbn() == item2.isbn())
    std::cout << "sum of sale items:\n" << item1 + item2 << std::endl;
  else
    std::cerr << "Different ISBN." << std::endl;
}
```

輸入/輸出：
```
0-201-78345-X 3 20
0-201-78345-X 3 60 20
0-201-78345-X 2 25
0-201-78345-X 2 50 25
sum of sale items:
0-201-78345-X 5 110 22
```

## 練習 1.22
寫一個程式讀取具有相同 ISBN 的數筆交易紀錄。寫出所讀取的所有交易紀錄之總和

解：
```cpp
#include <iostream>

#include "Sales_item.h"

int main() {
  Sales_item total;
  std::cin >> total;
  std::cout << total << std::endl;
  for (Sales_item trans; std::cin >> trans; std::cout << trans << std::endl)
    total += trans;
  std::cout << "sum of sale items:\n" << total << std::endl;
  return 0;
}
```

輸入/輸出：
```
0-201-78345-X 3 20
0-201-78345-X   3       60      20
0-201-78345-X 2 25
0-201-78345-X   2       50      25
0-201-78345-X 7 25
0-201-78345-X   7       175     25
sum of sale items:
0-201-78345-X   12      285     23.75
```

## 練習 1.23
寫一個程式，讀取數筆交易紀錄，並計數每個 ISBN 出現幾次
```cpp
#include <iostream>

#include "Sales_item.h"

int main() {
  Sales_item curItem, item;
  if (std::cin >> curItem) {
    int cnt = 1;
    while (std::cin >> item) {
      if (item.isbn() == curItem.isbn())
        ++cnt;
      else {
        std::cout << curItem.isbn() << " " << cnt << std::endl;
        curItem = item;
        cnt = 1;
      }
    }
    std::cout << curItem.isbn() << " " << cnt << std::endl;
  }
  return 0;
}
```

## 練習 1.24
給予前一個程式代表多個 ISBN 的多筆交易紀錄來測試它。每個 ISBN 的交易紀錄應該歸為同一組

解：

```cpp
#include <iostream>

#include "Sales_item.h"

int main() {
  Sales_item total;
  if (std::cin >> total) {
    Sales_item trans;
    while (std::cin >> trans) {
      if (total.isbn() == trans.isbn())
        total += trans;
      else {
        std::cout << total << std::endl;
        total = trans;
      }
    }
    std::cout << total << std::endl;
  } else {
    std::cerr << "No data?!" << std::endl;
    return -1;
  }
  return 0;
}
```
## 練習 1.25
使用網站上的 Sales_item.h 標頭，編譯並執行本節中的書店程式

```cpp
#include <iostream>
#include "Sales_item.h"

int main()
{
    Sales_item total;
    if (std::cin >> total)
    {
        Sales_item trans;
        while (std::cin >> trans)
        {
            if (total.isbn() == trans.isbn())
                total += trans;
            else
            {
                std::cout << total << std::endl;
                total = trans;
            }
        }
        std::cout << total << std::endl;
    }
    else
    {
        std::cerr << "No data?!" << std::endl;
        return -1;
    }
    return 0;
}
```