為什麼會有 ”size_t為何要存在” 的疑問?
許多C/C++檔案中都會出現類型
size_t
,比如在bitcoin源碼中,有這樣的一個函數:
size_t strnlen( const char *start, size_t max_len)
{
const char *end = (const char *)memchr(start, '\0', max_len);
//memchr函數從start開始尋找第一個出現字元'\0'的位置并傳回
return end ? (size_t)(end - start) : max_len;
//const char的長度吧,為啥要這樣寫,為什麼要單獨寫一個檔案啊,NOTE
}
該函數完成了傳回
const char*
類型
start
代表的串的長度,傳回值被設定為
size_t
類型。這是
size_t
經常被使用的一個場景“數組可能的長度。
另一個使用場景就是函數
memcpy
(其實本質上是一樣的,都是表示記憶體中資料的多少)。
memcpy
的原型
void* memcpy(void*to,const void*from,size_t n)
。需要複制的位元組數被設定為
size_t
類型,這是資料塊的大小。
于是,會給人一種感覺,這種工作
int
也可以完成,如果說需要排除負數,
unsigned int
也可以完成。為什麼要多此一舉引入
size_t
呢?
另外,為何要表示記憶體中所有的資料呢?為什麼不是硬碟?
這就是作業系統範疇的東西了。程式所使用的資料,一定是先由OS把資料搬/swap到記憶體,再根據記憶體位址去通路。至于怎麼從硬碟中找到,就是另一件事情了,它被叫做”缺頁中斷“。
為什麼需要size_t?
首先聲明
size_t
的功能,它需要保證在程式運作中可以表示所有記憶體位址。
size_t
根據具體機器的體系結構,将有不同的值。比如,32位系統,記憶體最大是\(2^{32} bytes=4G\)。那麼
size_t
就需要至少4個位元組(32bits)來表示所有位址。
即使是這樣,
unsigned int
不是也是4個位元組嗎?
有些系統是。
為了保證在一些有者特殊體系結構的機器上正确運作,使用
unsigned int
來表示資料塊大小可能是一個不好的主意。比如,一個機器支援16bit的
unsigned int
,但他是一個32位系統,使用
unsigned int
代替
size_t
顯然并不是一個好主意。假如出現一個特别大的數組,可能無法表示出這個數組所有的元素,顯而易見。
那麼,是否可以使用
unsigned long
來代替呢?畢竟,long一定需要至少32bits,那麼,對于那些隻有16位的平台呢,這些平台往往使用兩個16bits的字來對應一個
long
,在對
long
進行操作時,一定需要至少兩條操作指令。而在這個系統中,并不需要32bits的位址,因為他隻有16位。
要為了相容而舍棄性能嗎?顯然有更好的解決方案。那就是根據位址總線個數來決定一個類型的大小,既不會無法表示一些資料,又不會使一些機器效率折損。這個類型就是
size_t
。
size_t
的存在使得程式有更好的可移植性,顯而易見,程式員不需要為了一個新機器而在
unsigned int
和
unsigned char
等等類型之間改來改去。
size_t的使用
正如上述,
size_t
可以表示記憶體中的所有資料,因為它剛好能夠表示記憶體中所有的位址。
根據定義,
size_t
是關鍵字
sizeof
運算得到的結果的類型。是以,使用
sizeof
得到的結果應該聲明為
size_t
:
另外,就是第一小節所述的,表示數組大小、資料塊大小等等(實際上也是資料塊的大小)。
使用
size_t
的時候,記得包括它的定義所在頭檔案,比如
<stddef.h>, <stdio.h>, <stdlib.h>, <string.h>, <time.h>,<wchar.h>
中的任意一個。
Reference
為什麼size_t重要?
size_t類型
轉載于:https://www.cnblogs.com/riko707/p/11437328.html