理解C語言中的 size_t

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,而帶符號整型變量isize_t比較時會被類型提升自動轉換爲無符號整型unsigned int,數值-1轉化無符號整型數是4294967295,遠大於字符串長度5

帶符號數和無符號數之間的運算操作,請一定小心。

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章