https://zihengcat.github.io/2017/06/02/c-learning-notes-understanding-size_t/
前言
本文講解 C 語言中 size_t
類型及其應用。
size_t
類型
在 C 語言的標準頭文件中與很多內核項目中,都能發現 size_t
這個”數據類型”的身影,如函數參數、函數返回值、循環控制變量…似乎size_t
無處不在,可是我們又不太瞭解這個”數據類型”。
實際上,size_t
是個無符號整型,它並不是一個全新的數據類型,更不是一個關鍵字。size_t
是由typedef
定義而來的,我們在很多標準庫頭文件中都能發現。
C 標準頭文件<stddef.h>
中可以找到size_t
的實際定義。
...
#define __SIZE_TYPE__ long unsigned int
typedef __SIZE_TYPE__ size_t;
...
代碼清單:
<stddef.h>
中的size_t
在我個人的機器上,size_t
的真面目即:long unsigned int
。
使用 size_t
的緣由
查閱相關文檔後瞭解到,size_t
的含義是size type,是一種計數類型。取值範圍與機器架構與操作系統相關。32 位機器一般是unsigned int
,佔 4 字節;而 64 位機器一般是unsigned long
,佔 8 字節。
size_t
類型常被用作計數用途,例如:sizeof
運算符得到對象所佔的字節數;字符串函數strlen
返回字符串的長度等等,其返回值都爲size_t
類型。
size_t
類型隱含着本機理論所能容納建立最大對象的字節數大小的含義,因此常被用於數組索引、內存管理函數中。
最初設計size_t
類型初衷,是爲了程序的跨平臺兼容性考慮。
size_t
小陷阱
在 Google 搜索的時候,還發現了一個非常有趣的案例。
#include <stdio.h>
#include <string.h>
int main(void) {
int i = -1;
if (i < strlen("hello")) {
printf("Hello, World\n");
} else {
printf("Hello, ziheng\n");
}
return 0;
}
代碼清單:
size_t
陷阱
$ gcc test.c && ./a.out
Hello, ziheng
代碼清單:
size_t
程序執行結果
上述代碼編譯執行後,程序打印出了else
分支語句Hello, ziheng
,這似乎與預想的有些不同。
實際上,這段代碼的if
條件比較中觸發了 C 語言隱式自動類型轉換機制,size_t
實際類型爲unsigned long int
,而帶符號整型變量i
與size_t
比較時會被類型提升自動轉換爲無符號整型unsigned int
,數值-1
轉化無符號整型數是4294967295
,遠大於字符串長度5
。
帶符號數和無符號數之間的運算操作,請一定小心。