---
# System prepended metadata

title: C/C++ 的基本資料型態
tags: [C / C++]

---

# C/C++ 的基本資料型態

在 C 語言中宣告變數時，也必須宣告其資料型態，好讓電腦知道要分配出多少記憶體空間出來。

C 語言的基本資料型態可以分成三大類：

-   整數
-   浮點數
-   字元

## 整數

依記憶體大小可以細分為 `short int`、`int`、`long int`、`long long int`，不過實際的大小在不同編譯器的定義上不一定相同。此外，也可以依照最高位元是否為符號位元分為有符號數 (`signed`) 或無符號數 (`unsigned`)。

| 名稱                 | 記憶體大小   | 可表示範圍                                |
| -------------------- | ------------ | ----------------------------------------- |
| `short`              | 2 Bytes      | $-32,768$ ~ $32,767$                      |
| `int`                | 4 Bytes      | $-2^{31}$ ~ $2^{31}-1$ ($2,147,483,647$)  |
| `long`               | 4 或 8 Bytes |                                           |
| `long long`          | 8 Bytes      | $-2^{63}$ ~ $2^{63}-1$ (約 $9.2×10^{18}$) |
| `unsigned short`     | 2 Bytes      | $0$ ~ $65,535$                            |
| `unsigned int`       | 4 Bytes      | $0$ ~ $2^{32}-1$                          |
| `unsigned long`      | 4 或 8 Bytes |                                           |
| `unsigned long long` | 8 Bytes      | $0$ ~ $2^{64}-1$                          |

備註:

-   `short int`、`long int`、`long long int` 的 `int` 可以省略。
-   有符號數的 `signed` 可以省略。
-   `int` 亦可寫作 `signed`。
-   `unsigned int` 可寫作 `unsigned`。
-   `long long` 於 C99 加入。

## 布林值

C 語言原本是沒有布林值型態的，而是將 `0` 視為假 (`false`)，非 `0` 的值視為真 (`true`)。  
在 C99 時加入了 `bool` 型態 (大小為 1 Byte)，其定義於標頭檔 `<stdbool.h>` 中；另外也定義了 `true` 和 `false` 分別表示 `1` 和 `0`。

## 浮點數

依記憶體大小可以細分為 `float`、`double`、`long double`。其格式使用 IEEE 754 標準。

| 名稱          | 記憶體大小 | 有效位數 |
| ------------- | ---------- | -------- |
| `float`       | 4 Bytes    | 約 7 位  |
| `double`      | 8 Bytes    | 約 16 位 |
| `long double` | 16 Bytes   | 約 19 位 |

## 字元

由於電腦只認識 `0` 和 `1`，看不懂人類的字母，因此我們需要定義一些代碼來表示字元，常用的字元編碼為 ASCII。  
而 `char` 實際上是儲存字元的編碼數值，因此也可以用來儲存較小範圍的整數。與整數相同的，可以根據有無符號位元分為 `signed char` 和 `unsigned char`。

| 名稱          | 記憶體大小 | 可表示範圍     |
| ------------- | ---------- | -------------- |
| char          | 1 Bytes    | $-128$ ~ $127$ |
| signed char   | 1 Bytes    | $-128$ ~ $127$ |
| unsigned char | 1 Bytes    | $0$ ~ $255$    |

備註:

-   有些編譯器會將 `char` 視為無符號數，即 `unsigned char`。

### ASCII

ASCII 一種字元編碼系統，主要用來顯示現代英語。其編碼主要可以分為控制字元與可顯示字元。

控制字元的編碼範圍是 0 ~ 31 和 127 (`0x00` ~ `0x1F` 和 `0x7F`)，無法直接顯示於螢幕上。

可顯示字元的編碼範圍是 32 ~ 126 (`0x20` ~ `0x7E`)，其中 32 為空格 (` `)、48 ~ 57 為阿拉伯數字 (`0` ~ `9`)、65 ~ 90 為大寫英文字母 (`A` ~ `Z`)、97 ~ 122 為小寫英文字母 (`a` ~ `z`)，其餘為一些常用的符號。

由於 ASCII 只能表示基本的英文字母，而無法表示其他語言的字母。後來就延伸出了其他編碼方式，例如 Unicode、EASCII、Big5、GBK、Shift_JIS 等適用於不同語言的編碼。

### 跳脫字元

有些字元著特殊意義，例如單引號 (`'`) 表示字元、雙引號 (`"`) 表示字串 (字元陣列)，或是有些字元無法在鍵盤上直接打出來，例如換行、ASCII 控制字元等，這時我們就可以用跳脫字元加上一些代號來表示著些特殊符號，而在 C 語言中，我們使用反斜線 (`\`) 來表示跳脫字元。

常見的跳脫字元如下：

| 符號         | 含意                              | 備註                   |
| ------------ | --------------------------------- | ---------------------- |
| `\'`         | 單引號 (`'`)                      |                        |
| `\"`         | 雙引號 (`"`)                      |                        |
| `\\`         | 反斜線 (`\`)                      |                        |
| `\0`         | 空字元 (NUL)                      | 不是空白也不是數字 `0` |
| `\b`         | 退格 (BS)                         | `Backspace` 鍵         |
| `\r`         | 回車 (CR)                         | 回到該行的開頭         |
| `\n`         | 換行 (LF)                         |                        |
| `\f`         | 換頁 (FF)                         |                        |
| `\t`         | 水平定位符號 (HT)                 | `tab` 鍵               |
| `\v`         | 垂直定位符號 (VT)                 | 垂直版的 `tab`         |
| `\000`       | 使用八進位表示值                  |                        |
| `\x00`       | 使用十六進位表示值                |                        |
| `\u0000`     | 使用十六進位表示 Unicode 內碼     |                        |
| `\U00000000` | 使用十六進位表示更長 Unicode 內碼 |                        |

範例:

```c
#include <stdio.h>

int main()
{
    printf("HelloWorld!\n");
    printf("Hello\bWorld!\n");
    printf("Hello\rWorld!\n");
    printf("Hello\nWorld!\n");
    printf("Hello\fWorld!\n");
    printf("Hello\tWorld!\n");
    printf("Hello\vWorld!\n");
    printf("A\102\x43 \u4f60\u597d\U0001f600\n");
    return 0;
}
```

輸出:

```
HelloWorld!
HellWorld!
World!
Hello
World!
Hello
     World!
Hello   World!
Hello
     World!
ABC 你好😀
```


## 字面常數 (literal constant)

字面常數也就是我們在程式碼中所寫的那些定值，例如: `0`、`1.3`、`'a'` 等，當然我們也可以依照它們的格式來區分型別。

### 整數

我們可以在整數前面加上一些前綴，來表示進位制:

| 前綴 | 進位制   | 範例                         |
| ---- | -------- | ---------------------------- |
| (無) | 十進位   | `123`                        |
| `0`  | 八進位   | `031` ($31_8 = 25_{10}$)     |
| `0x` | 十六進位 | `0x5d` ($5D_{16} = 93_{10}$) |
| `0b` | 二進位   | `0b101` ($101_2 = 5_{10}$)   |

整數預設為 `int` 型別，不過也會依照值的大小使用可表示範圍更大的整數型別。當然，我們也可以加上一些後綴，來明確表示型別:

| 後綴 | 型別        |
| ---- | ----------- |
| (無) | `int`       |
| `u`  | `unsigned`  |
| `l`  | `long`      |
| `ll` | `long long` |

### 浮點數

如果小數點 (`.`) 前或後為零的話可以省略，但不可以同時都省略，如: `1.`、`.45`。

我們也可以使用科學記號的形式來表示浮點數，其又分為十進位與十六進位。
十進位使用字母 `e` 來區分尾數和指數，如: `2.9e23` 表示 $2.9×10^{23}$、`3.6e-2` $3.6×10^{-2}$。
十六進位使用字母 `p` 來區分尾數和指數，其中尾數須加上前綴 `0x` 表示為十六進位制，而指數則是使用十進位表示為 2 的幾次冪，如:`0x1p10` 表示 $1_{16}×2^{10} = 1024_{10}$、`0x1.85fp-23` 表示 $1.85F_{16}×2^{-23} = 1.815788×10^{-7}$。

與整數相同的，我們也可以加上一些後綴，來表示型別:

| 後綴 | 型別          |
| ---- | ------------- |
| (無) | `double`      |
| `f`  | `float`       |
| `l`  | `long double` |

### 字元

就是用一對單引號 (`''`) 包住一個字元，如: `'a'`、`'B'`、`'5'`。
