天天看點

size_t——為什麼支援size_t,何時使用size_t?

為什麼會有 ”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

繼續閱讀