由 C 入手 C++ 的小撇步 === 作者:張頌宇 這是寫給對於 C 語言有一定程度了解的人看的。 下面會舉出一些常見的 C 語言和 C++ 不一樣的地方。 標頭檔(Header File) --- 標頭檔是指一些已經寫好的東西,有分成內建的和自訂的。 我們可以透過 `#include` 標籤來匯入標頭檔。 ### 內建的 我們習慣用角括號`<>`把檔名包起來,在 C 語言寫起來像是 ```=C #include <stdio.h> ``` 不一樣的地方: 在 C 語言裡面,內建的標頭檔是`.h`結尾,但 C++ 不需要`.h`結尾, 而且如果想在 C++ 裡面用原本 C 語言當中的標頭檔,會在前面加上一個 c。 範例: 這是 C 語言的 ```=C #include <stdio.h> /* C 的輸入輸出函式庫 */ #include <stdlib.h> /* C 的通用函式庫 */ ``` 這是 C++ 使用 C 語言的 ```=C++ #include <cstdio> /* C 的輸入輸出函式庫 */ #include <cstdlib> /* C 的通用函式庫 */ ``` 這是 C++ 特有的 ```=C++ #include <iostream> /* C++ 的輸入輸出資料流函式庫 */ ``` ### 自訂的 我們習慣用角括號`""`把檔名包起來,在 C 語言寫起來像是 ```=C #include "mylib.h" ``` 這部分基本上 C++ 就和 C 語言一樣了。 For 迴圈(for loop) --- 以前在 C 的時候,我們會在 for 迴圈前面先宣告變數, 現在在 C++ 當中可以在初始條件的地方再宣告。 範例: C 語言 ```=C int i; for (i = 0; i < 10; i++) { /* your code */ } ``` C++ ```=C++ for (int i = 0; i < 10; i++) { /* your code */ } ``` 輸入輸出(Input/Output)與資料流(Data Stream) --- 以前在 C 當中如果要處理輸入/輸出,肯定會用 scanf 和 printf。 現在 C++ 引入了一個「資料流」的概念,讓輸入/輸出更方便。 注意:C++ 使用 `std::cout` 等等記得引用 `iostream` 標頭檔!! 舉個例子(輸出 Hello World): C 語言的寫法 ```=C #include <stdio.h> int main() { print("Hello World\n"); return 0; } ``` C++ 的寫法 ```=C++ #include <iostream> int main() { std::cout << "Hello World" << std::endl; return 0; } ``` std 是 standard(標準)的名稱空間(後面會提到), cout 是 C++ 的 output 的縮寫, endl 是 End of line 的縮寫(作用等同以前的 `"\n"`), `<<` 就像是推出去(由 std::cout 印出來)的意思。 再看個例子(輸入): C 語言的寫法 ```=C #include <stdio.h> int main() { int number; scanf("%d", &number); return 0; } ``` C++ 的寫法 ```=C++ #include <iostream> int main() { int number; std::cin >> number; return 0; } ``` std 是 standard(標準)的名稱空間(後面會提到), cin 是 C++ 的 input 的縮寫, `>>` 就像是由 std::cin 吃進去的意思。 物件導向的語法(Object Oriented) --- 物件導向是一種程式設計的思維, 參看 Jserv 大大的文章:[你所不知道的 C 語言:物件導向程式設計篇](https://hackmd.io/@sysprog/c-prog/%2Fs%2FHJLyQaQMl)。 雖然說「物件導向是一種態度」,不需要程式語言提供語法才能寫, 不過 C++ 還是好心提供了物件導向的語法,讓撰寫更方便。 物件(Object)雖然沒有像變數和 function 那樣基礎,但卻是很重要的精神! 真實世界的東西大都是以物件的形式呈現的,我們在討論的很多東西都是物品或實體。 物件可以被其他物件組裝起來,也有屬於自己的一些動作。 舉例來說,車子是一個物件: 車子是由許多物件組成:4個輪子、方向盤、座位、...(很像是屬於車子的變數) 也有屬於它的一些行為:前進、左轉、右轉、後退、...(很像是屬於車子的 function) 所以說我們把很多屬於車子的變數、function 包裝起來,就可以很方便使用和理解,這也就是物件為何這麼重要的原因! 註:習慣上我們通常會把物件的 function 叫做 「method(方法)」。 有關物件導向的部分請參考 C++ 的書,就不細談了。 名稱空間(Namespace) --- 名稱空間的概念有點像是我們用資料夾把檔案做分類。 因為一個大型的程式可能會有數百個以上的函式、變數、類別、物件等等, 可能會出現我在不同地方卻想取相同名字的困擾, 所以我們就可以用「名稱空間」幫這些東西分類! 就像是施洗者約翰、耶穌的門徒約翰,雖然都叫約翰,但是是不同人。 怎麼做呢? 在資料夾的例子中,我們會用斜線 `/` 來做資料夾層級的區隔, 在名稱空間,我們則是用兩個冒號 `::` 來做區隔。 例子: ```=C++ std::cout std::endl std::cin std::string boost::asio::ip::tcp ``` 所以我們可以看到 cout 是屬於名稱空間 std 的一個東西, boost 名稱空間下有 asio 名稱空間,下面還依序有 ip、tcp 名稱空間。 是不是就像用資料夾分類一樣呢!? 註:我們常常會看到 std 這個名稱空間,std 就是 standard 的簡寫, C++ 所提供的內建函式庫幾乎都屬於 std 名稱空間喔! ### using namespace 雖然名稱空間幫我們解決了取名字可能會衝突的問題,但他有一個缺點, 就是「落落長」! 如果我們非常確定我們的程式當中不會出現有衝突的名字,我們卻需要用到名稱空間中的東西的話,我們可以做些簡化,就是在前面加上 `using namespace 你想用的名稱空間`,就不用每次都把名稱空間打出來囉! 範例(我們拿前面輸出 Hello World 的例子): 原本是 ```=C++ #include <iostream> int main() { std::cout << "Hello World" << std::endl; return 0; } ``` 後來變成 ```=C++ #include <iostream> using namespace std; int main() { cout << "Hello World" << endl; return 0; } ``` 只要在最前面加上 `using namespace std;`, 這樣就不用每次都要把煩人的 `std::` 打出來囉,因為程式自己會去 std 裡面找有沒有 cout、endl 這些東西。