数据类型 (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++的兼容性。