--- tags: C++教學筆記 --- # 變數與常數 ## 變數的名稱 變數名稱的規定並沒有很嚴格,只有以下幾點是需要遵守的: * 變數名稱中只能有英文字母、下劃線`_` 、美元符號 `$` 及數字。 * 不能使用 c/c++ 的關鍵字作為變數名稱 `(e.g. new、float 等)`。 * 不能以數字作為開頭。 一般會建議變數名稱要盡量取得有意義,否則變數變多時程式碼會變得難以閱讀。 以下有幾種潛規則可以遵循: * **駝峰式命名**: 首字小寫,換單字的第一個字母大寫 `(e.g. pricePerMeter)`。 * **以底線分隔單字** `(e.g. price_per_meter)`。 以上兩種選一種使用即可,駝峰式命名是現在較為主流的命名方法。 * 常數`const`及巨集`define`名稱全大寫,以底線分隔單字 `(e.g. NUMBER_OF_STUDENT)`。 * 若意義相同,盡量縮短變數或常數名稱。 --- ## 資料型態 c++中自帶了許多不同的資料型態, | 類型 | 型態名稱 | 記憶體大小 | 資料範圍 | 備註 | | ------- | -------- | -------- | -------- | -------- | | **整數** | short <br> int <br> long long| 2 bytes <br> 4 bytes <br> 8 bytes | $-2^{15}$ **~** $2^{15}-1$ <br> $-2^{31}$ **~** $2^{31}-1$ <br> $-2^{63}$ **~** $2^{63} -1$ | 這三者皆可以加上 `unsigned` 修飾 <br> 加上 `unsigned` 後僅能儲存正數 <br> 但是資料範圍變兩倍大 | | **浮點數** | float <br> double | 4 bytes <br> 8 bytes | $3.4E \pm 38$ <br> $1.7E \pm 308$ | 亦可以加上 `unsigned` 修飾字 <br> 效果同整數型別 | | **字元** | char | 1 byte | -128~127 | c++使用 [ASCII](https://zh.wikipedia.org/zh-tw/ASCII) 存取字元型態 | | **布林** | bool | 1 byte | -- | 僅儲存 `true` `false` | --- ## 變數宣告與初始化 若在程式中需要使用到一個變數,那我們必須在使用之前先宣告這個變數。 宣告的格式為 `資料型態 變數名稱;` 假設我們要宣告一個整數變數,名稱為a,則看起來會像: ```cpp int a; ``` 我們也可以在宣告變數的同時給他一個初始值,這個行為稱為初始化。 以同樣的例子,假設這次我們想要讓a的初始值為10,則有以下兩種寫法: ```cpp int a = 10; int a(10); ``` 通常以第一種較為常見,也比較容易閱讀。 > 若沒有手動給予初始值,根據不同的編譯器會給予不同的初值(未定義行為,undefined behavior), 所以請不要在沒有給任何值的情況下使用變數。 除了可以給予10進位初始值外,也可以給予16進位初始值,寫法如下: ```cpp int a = 0x66aaff; int a(0x66aaff); ``` --- ## 基本輸出輸入 * **輸入** 在c++中,我們最常使用的基本輸入物件是 `cin`, 要使用 `cin` ,我們需要搭配右移運算子`>>`來使用, 假設我們要輸入一個整數代表學生的成績,那程式碼如下: ```cpp int score; cin >> score; ``` 如此就完成了輸入。 而 `cin` 也可以連續輸入多個變數,不用是相同的型態也沒問題。 假設我們要輸入學生的學號、成績及性別(用字元代表),那程式可以寫成: ```cpp int stuNum, score; char gender; cin >> stuNum >> score >> gender; ``` 這時就要再講到 `cin` 的一個特性: 不論是空白或是換行,都不會被 `cin` 讀取到 所以我們的輸入只要像是 `110123001 75 B` 的形式即可(當然,換行也可以)。 * **輸出** 而在c++中,最常被使用的基本輸出物件是 `cout`, 要使用 `cout` ,和 `cin` 相反,我們需要搭配左移運算子`<<`來使用, 其餘用法都與 `cin` 很相似。 以上面的程式碼為例,假設我們輸入結束後想要輸出一次結果來確認自己有沒有打錯,我們可以寫成: ```cpp int stuNum, score; char gender; cin >> stuNum >> score >> gender; cout << "你輸入的學號: " << stuNum << endl; cout << "你輸入的成績: " << score << endl; cout << "你輸入的性別: " << gender << endl; ``` 以同樣的輸入`110123001 75 B` ,我們可以得到輸出結果是: ``` 你輸入的學號: 110123001 你輸入的成績: 75 你輸入的性別: B ``` 其中,我們可以用雙引號 `"` 來夾住我們想要固定輸出的內容,使它成為一個「字串常數」。 而 `endl` 代表的是換行,請記住c++的輸出並不會幫你空格或換行。 * **幫助記憶的小撇步(?** 我們可以把 `cin` `cout` 想像成我們的電腦, `cin >> 變數` 就像是從電腦從輸入裝置 `(e.g.鍵盤)` 把資料灌進變數裡面, `cout << 變數` 就像是變數一個一個流進電腦的輸出裝置 `(e.g.螢幕)` 裡面, 這樣想像也可以很容易理解輸入輸出的順序,也很符合c++中輸入輸出流 `iostream` 的概念。 --- ## 溢位 在前面資料型態的表格中有提到,不同的資料型態有不同的記憶體大小,造成他們可以儲存的資料範圍也有所不同。 如果給出了超過範圍的值,程式做出的行為可能會跟我們所想的完全不同。 以下面這段程式碼為例: ```cpp short a = 30000; cout << a << endl; a = a + 3000; cout << a << endl; ``` 若以我們直覺的角度來想,我們會覺得輸出應該是: ``` 30000 33000 ``` 不過實際執行出來的結果會是: ``` 30000 -32536 ``` 若我們回去看表格,就會發現 `short` 只能儲存-32768~32767這個範圍的整數,33000明顯超出了這個範圍,我們不妨再做個小實驗: ```cpp short a = 32767; cout << a << endl; a = a + 1; cout << a << endl; ``` 會發現它的輸出是: ``` 32767 -32768 ``` 所以就可以知道當資料超過範圍的上限時,裡面的值會從下限的值開始運算,這個現象就稱作溢位`overflow`,那就不難理解最上面那段程式碼的輸出了(可以自己算算看)。 --- ## 跳脫字元 | 跳脫字元 | 功能 | ASCII 編碼 |ASCII 符號 | | -------- | -------- | -------- |-------- | | \n | 換行 | 10 | NL(LF) | | \r | 歸位,移至首行,但不換行 | 13 | CR | | \t | 移到定位點 | 9 | HT | | \0 | 空 | 0 | NULL | | \\? | 印出問號`?` | 63 | ? | | \\\ | 印出反斜線`\` | 92 | \ | | \\' | 印出單引號`'` | 39 | ' | | \\" | 印出雙引號`"` | 34 | " | --- ## 常數宣告 在數學上有許多常數,例如 $\pi$ 、$e$ 等等,各代表著不同的數值; 我們在程式中也常常會有需要使用到常數的情形,例如最大人數上限等等,這時候我們就可以宣告一個常數來給我們使用。 * 常數的宣告非常簡單,只要把變數宣告的前面加上`const`修飾字即可,例如: ```cpp const int MAX_SIZE = 100; ``` 如此就完成了 `MAX_SIZE` 的常數宣告。 * 另一種方法是使用巨集 `define` 的功能,當程式在運行時碰到巨集的名稱時,會自動替換成巨集的內容。以同樣的例子,程式碼會是如下: ```cpp #define MAX_SIZE 100 ``` 當我們在程式中使用 `MAX_SIZE` 時,編譯器會自動把 `MAX_SIZE` 替換成`100`,這種方式也可以達到類似常數宣告的目的。