數據類型 (C語言)

在C語言中，數據類型可以分為兩類：基礎數據類型和複合數據類型。

## 基礎數據類型

注意：以下是典型的數據位長和範圍。編譯器可能使用不同的數據位長和範圍。請參考具體的參考。

在標準頭文件limits.h 和 float.h中說明了基礎數據的長度。float，double和long double的範圍就是在IEEE 754標準中提及的典型數據。另外，C99添加了新的複數類型，C11添加了原子類型，它們不在本條目討論範圍內。關於這些類型的具體含義和部分細節，參見資料類型，最後一列寫出了這些類型在硬體層面的類型（x86&x86_64實現)

關鍵字｜位元組（字節）｜範圍｜格式化字符串｜硬體層面的類型｜備註

`char`｜1bytes｜通常為-128至127或0至255，與體系結構相關｜%c｜字節(Byte)｜大多數情況下即`signed char；` 在極少數1byte != 8bit或不使用ASCII字符集的機器類型上範圍可能會更大或更小。其它類型同理。

`unsigned char`｜1bytes｜通常為0至255｜%c、%hhu｜字節

`signed char`｜1bytes｜通常為-128至127｜%c、%hhd、%hhi｜字節

`int`｜2bytes(16位系統) 或4bytes｜-32768至32767或-2147483648至2147483647｜%i、%d｜字(Word)或雙字(Double Word)｜即`signed int`(但用於bit-field時，int可能被視為signed int，也可能被視為unsigned int)

`unsigned int`｜2bytes 或4bytes｜0至65535 或0至4294967295｜%u｜字或雙字

`signed int`｜2bytes 或4bytes｜-32768至32767 或-2147483648至2147483647｜%i、%d｜字或雙字

`short int`｜2bytes｜-32768至32767｜%hi、%hd｜字｜即`signed short`

`unsigned short`｜2bytes｜0至65535｜%hu｜字

`signed short`｜2bytes｜-32768至32767｜%hi、%hd｜字

`long int`｜4bytes 或8bytes｜-2147483648至2147483647 或-9223372036854775808至9223372036854775807｜%li、%ld｜長整數(Long Integer)｜即`signed long`

`unsigned long`｜4bytes 或8bytes｜0至4294967295 或0至18446744073709551615｜%lu｜整數(Unsigned Integer)或 長整數(Unsigned Long Integer)｜依賴於實現

`signed long`｜4bytes或8bytes｜-2147483648至2147483647 或-9223372036854775808至9223372036854775807｜%li、%ld｜整數(Signed Integer)或 長整數(Signed Long Integer)｜依賴於實現

`long long`｜8bytes｜-9223372036854775808至9223372036854775807｜%lli、%lld｜長整數(Long Integer)

`unsigned long long`｜8bytes｜0至18446744073709551615｜%llu｜長整數(Unsigned Long Integer)

`float`｜4bytes｜-3.403x10+38至3.403x10+38 (7 sf)｜%f、%e、%g｜浮點數(Float)

`double`｜8bytes｜-1.798x10+308至1.798x10+308 (15 sf)｜%lf、%e、%g｜雙精度浮點型(Double Float)

`long double`｜10bytes或16bytes｜-1.189x10+4932至1.189x10+4932 (18 sf或33 sf)｜%Lf、%Le、%Lg｜雙精度浮點型(Double Float)｜在大多數平台上的實現與`double`相同，實現由編譯器定義。

`_Bool`｜1byte｜0或1｜%i、%d｜布爾型(Boolean)

註：粗體為C99所新增的類型。

## 複合數據類型

在C語言中，複合數據類型可分為三類：結構、聯合和枚舉。在現代C語言中，聯合和枚舉的使用頻率已逐漸減少。

### 結構

結構（structure variable）允許構造由多個基礎數據類型組合而成的複雜結構。結構為面向對象編程的藍本。以下示例通過結構和結構體裡的指針實現了二叉樹結構：

```c
typedef struct Bintree {
    int data;
    struct bintree *lchild; // left child of the node
    struct bintree *rchild; // right child of the node
} bintree; // 自定义 bintree 类型
```

為結構定義變量時通常會用到動態記憶體分配：

```c
#define mktree() (bintree *)malloc(sizeof(bintree)) // 分配该结构所需的内存单元数量
bintree *tree;
tree = mktree(); // 分配到 tree 指针
tree->data = 1;
tree->lchild = mktree();
...
```

由於C語言不具備自動垃圾收集（Garbage Collection）功能，使用完畢後調用`free(treePtr)`來釋放之前通過`malloc(size)`分配的記憶體。詳見這裡。

在C99標準中，還添加了名為伸縮型陣列成員的特性，關於此特性的內容超出了該條目的介紹範圍，若需了解更多資訊可參見文檔或其它材料。

### 聯合

聯合（union）與結構相類似，但不同的是，聯合在某一特定時刻只有最後被使用的成員的值是確定的，因此一個聯合只使用所有成員中所占空間最大的成員所使用的記憶體。然而，一些編譯器可以通過編譯參數或#pragma的方式強制聯合使用與所有成員所占儲存空間的和相等的儲存空間，在這種情況下，除最後被使用的成員外，其餘成員的值是未定義的。以下給出了聯合的一個聲明：

```c
union foo{
    int bar;
    double foobar;
};

foo.bar = 8;
foo.foobar = 3.14;
```

在這個例子中，假設使用32位平台編譯，一個double變量占8位元組，一個int變量占2位元組（由上表得），則該聯合所占大小即為double類型的大小——8位元組。在這段程序執行完畢後，foo.bar的值是未定義的，而foo.foobar的值為3.14。

### 枚舉

枚舉（enumerated type）用來聲明一組整數常量。默認情況下，枚舉聲明格式為enum type {value1,value2,...,valuen};此時value1,value2分別為0，1，直到n-1。事實上，枚舉類型在C語言實現中是以int類型儲存的。以下是枚舉的一個聲明：

```c
enum a { b , c , d };
```

在此之後，便可以以如下方式使用：

```c
enum a foo;
foo = b;
if(foo != c) //等同于if(foo != 1)
{
    do_something();
}
```

而此時的b，c，d分別為0，1，2。

另外，也可以手動為枚舉列表中的常量賦值。下面是一個例子：

```c
enum colour {red = 100,blue = 700,yellow = 200};
```

則此時red，blue，yellow的值分別為100，700，200.

需要注意的是，枚舉在C和C++中所表現的行為有一些細微的差異。參見C與C++的兼容性。