1. 程式人生 > >size_t 資料型別

size_t 資料型別

size_t

size_t 是一些C/C++標準在stddef.h中定義的,size_t 型別表示C中任何物件所能達到的最大長度,它是無符號整數。

它是為了方便系統之間的移植而定義的,不同的系統上,定義size_t 可能不一樣。size_t在32位系統上定義為 unsigned int,也就是32位無符號整型。在64位系統上定義為 unsigned long ,也就是64位無符號整形。size_t 的目的是提供一種可移植的方法來宣告與系統中可定址的記憶體區域一致的長度。

size_t 在陣列下標和記憶體管理函式之類的地方廣泛使用。例如,size_t 用做sizeof 操作符的返回值型別,同時也是很多函式的引數型別,包括malloc 和strlen。

在宣告諸如字元數或者陣列索引這樣的長度變數時用size_t 是好的做法。它經常用於迴圈計數器、陣列索引,有時候還用在指標算術運算上。size_t 的宣告是實現相關的。它出現在一個或多個標準標頭檔案中,比如stdio.h 和stblib.h,典型的定義如下:

#ifndef __SIZE_T
#define __SIZE_T
typedef unsigned int size_t;
#endif

define 指令確保它只被定義一次。實際的長度取決於實現。通常在32 位系統上它的長度是32 位,而在64 位系統上則是64 位。一般來說,size_t 可能的最大值是SIZE_MAX。

列印size_t 型別的值時要小心。這是無符號值,如果選錯格式說明符,可能會得到不可靠的結果。推薦的格式說明符是%zu。不過,某些情況下不能用這個說明符, 作為替代,可以考慮%u 或%lu。下面這個例子將一個變數定義為size_t,然後用兩種不同的格式說明符來列印:

size_t sizet = -5;
printf("%d\n",sizet);
printf("%zu\n",sizet);

因為size_t 本來是用於表示正整數的,如果用來表示負數就會出問題。如果為其賦一個負數,然後用%d 和%zu 格式說明符列印,就得到如下結果:

-5
4294967291

%d 把size_t 當做有符號整數,它打印出-5 因為變數中存放的就是-5。%zu 把size_t 當做無符號整數。當-5 被解析為有符號數時,高位置為1,表示這個數是負數。當它被解析為無符號數時,高位的1 被當做2 的乘冪。所以在用%zu 格式說明符時才會看到那個大整數。

sizet = 5;
printf("%d\n",sizet); // 顯示5
printf("%zu\n",sizet); // 顯示5

因為size_t 是無符號的,一定要給這種型別的變數賦正數 。

ssize_t

ssize_t 和size_t類似,但必需是signed(表示 signed size_t型別), 用來表示可以被執行讀寫操作的資料塊的大小

size_t 和 int 比較

  • size_t在32位架構中定義為:typedef   unsigned int size_t;
  • size_t在64位架構中被定義為:typedef  unsigned long size_t;
  • size_t是無符號的,並且是平臺無關的,表示0-MAXINT的範圍;int為是有符號的;
  • int在不同架構上都是4位元組,size_t在32位和64位架構上分別是4位元組和8位元組,在不同架構上進行編譯時需要注意這個問題。
  • ssize_t有符號整型,在32位機器上等同與int,在64位機器上等同與 long int.

C語言程式設計需要注意的64位和32機器的區別  

  char short int long long long 指標
16 位 平臺 1Byte 8位 2Byte 16位 2Byte 16位 4Byte 32位   2 Byte
32 位 平臺

1Byte 8位

2Byte 16位 4Byte 32位 4Byte 32位 8 Byte 64位 4 Byte
64 位 平臺 1Byte 2Byte 4Byte 8Byte 8Byte 8Byte

程式設計注意事項

為了保證平臺的通用性,程式中儘量不要使用long資料庫型。可以使用固定大小的資料型別巨集定義,這些巨集定義需要引用stdint.h標頭檔案:

typedef signed char int8_t
typedef short int int16_t;
typedef int int32_t;
# if __WORDSIZE == 64
    typedef long int int64_t;
# else
    __extension__
    typedef long long int int64_t;
#endif

intptr_t

使用int時也可以使用intptr_t來保證平臺的通用性,它在不同的平臺上編譯時長度不同,但都是標準的平臺字長,比如64位機器它的長度就是8位元組,32位機器它的長度是4位元組,使用它可以安全地進行整數與指標的轉換運算,也就是說當需要將指標作為整數運算時,將它轉換成intptr_t進行運算才是安全的。intptr_t需要引用stddef.h標頭檔案,它的定義如下:

#if __WORDSIZE == 64
    typedef long int intptr_t;
#else
    typedef int intptr_t;
#endif

程式設計中要儘量使用sizeof來計算資料型別的大小。以上型別定義都有相應的無符號型別。

使用ssize_t和size_t

它們分別是unsigned和signed size of computer word size。它們也是表示計算機的字長,在32位機器上是int型,在64位機器上long型。使用它們對於增加平臺的通用性有很大好處,從某種意義上來說它們等同於intptr_t和uintptr_t。使用它們也需要引用stddef.h標頭檔案。

socket的accept函式在有些作業系統上使用size_t是不正確的,因為accept接收的int*型別,而size_t的長度可能會超過int*的長度限制,導致錯誤。後來BSD使用sock_t來替代它。

 

參考:https://blog.csdn.net/bzhxuexi/article/details/19899803

           https://blog.csdn.net/qq_30866297/article/details/51465473