數據類型 (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[1] |
-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 | 2.939x10−38至3.403x10+38 (7 sf) | %f、%e、%g | 浮點數(Float) | |
double |
8bytes | 5.563x10−309至1.798x10+308 (15 sf) | %lf、%e、%g | 雙精度浮點型(Double Float) | |
long double |
10bytes或 16bytes |
7.065x10-9865至1.415x109864 (18 sf或33 sf) | %lf、%le、%lg | 雙精度浮點型(Double Float) | 在大多數平台上的實現與double 相同,實現由編譯器定義。
|
_Bool
|
1byte | 0或1 | %i、%d | 布爾型(Boolean) |
註:粗體為C99所新增的類型。
複合數據類型
編輯在C語言中,複合數據類型可分為三類:結構、聯合和枚舉。在現代C語言中,聯合和枚舉的使用頻率已逐漸減少。
結構
編輯結構(structure variable)允許構造由多個基礎數據類型組合而成的複雜結構[2]。結構為面向對象編程的藍本。以下示例通過結構和結構體裡的指針實現了二叉樹結構:
typedef struct Bintree {
int data;
struct bintree *lchild; // left child of the node
struct bintree *rchild; // right child of the node
} bintree; // 自定义 bintree 类型
為結構定義變量時通常會用到動態內存分配:
#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標準中,還添加了名為伸縮型數組成員的特性[3],關於此特性的內容超出了該條目的介紹範圍,若需了解更多信息可參見文檔或其它材料。
聯合
編輯聯合(union)與結構相類似,但不同的是,聯合在某一特定時刻只有最後被使用的成員的值是確定的,因此一個聯合只使用所有成員中所占空間最大的成員所使用的內存。然而,一些編譯器可以通過編譯參數或#pragma的方式強制聯合使用與所有成員所占儲存空間的和相等的儲存空間,在這種情況下,除最後被使用的成員外,其餘成員的值是未定義的[2]。以下給出了聯合的一個聲明:
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類型儲存的[2]。以下是枚舉的一個聲明:
enum a { b , c , d };
在此之後,便可以以如下方式使用:
enum a foo;
foo = b;
if(foo != c) //等同于if(foo != 1)
{
do_something();
}
而此時的b,c,d分別為0,1,2。 另外,也可以手動為枚舉列表中的常量賦值。下面是一個例子:
enum colour {red = 100,blue = 700,yellow = 200};
則此時red,blue,yellow的值分別為100,700,200.
需要注意的是,枚舉在C和C++中所表現的行為有一些細微的差異。參見C與C++的兼容性。
參考文獻
編輯- ^ GCC、Clang 等實現中,64位代碼的long類型為64位,而MSVC中則維持32位
- ^ 2.0 2.1 2.2 ISO/IEC 9899:2018 (PDF). [2020-06-10]. (原始內容存檔 (PDF)於2020-07-22).
- ^ ISO/IEC 9899:1999 (PDF). [2020-06-15]. (原始內容存檔 (PDF)於2018-01-11).