首先我們進(jìn)行一個實(shí)驗(yàn):
char str[] = "asdfg";
char *pstr = "asdfg";
std::cout << sizeof(str) << " " << sizeof(pstr);
得到的結(jié)果是:6,4
同樣的,我們再試一下:
size_t size2(int a[])
{
return sizeof(a);
}
size_t Size3(int* a)
{
return sizeof(a);
}
int main()
{
int arr[20];
std::cout << sizeof(arr) << " " << size2(arr) << " " << Size3(arr)<<std::endl;
std::cout<<sizeof((int*)a);
}
得到的是:80,4,4,4
我們發(fā)現(xiàn)只有直接引用數(shù)組名的時候,得到的size才是數(shù)組的大小
為什么會這樣呢?
- 我們經(jīng)常說數(shù)組名就是指針,其實(shí)不太嚴(yán)謹(jǐn)。數(shù)組名和普通的指針有一些不一樣。數(shù)組名是一個常量指針,我們不可以改變其值。
- 在某些情況下其語義會發(fā)生改變,比如
sizeof(name_of_array)的時候,數(shù)組名代表的是一個數(shù)組,因此我們可以得到數(shù)組的大小 - 對數(shù)組名取地址也是合法的
std::cout << arr<<" "<<&arr;得到的結(jié)果是一樣的:

指向數(shù)組名的指針.png
但是普通的指針:
int b = 10;
int* a = &b;
std::cout << a << " " << &a<<" ";
這兩個的結(jié)果是不同的:

普通指針的地址
-
在函數(shù)的參數(shù)傳遞過程中,地址常量可以退化成對應(yīng)的指針
就比如size2(int a[])函數(shù)一樣,數(shù)組名不再代表數(shù)組,而是轉(zhuǎn)換為普通的指針,指針(32位下)占4個Byte
4.3更新:
如果sizeof的對象是函數(shù),則返回函數(shù)返回值類型大??;
并且不會去執(zhí)行函數(shù);
同理如果sizeof的對象是表達(dá)式,也是返回表達(dá)式結(jié)果的類型大小,而不執(zhí)行表達(dá)式。注意c_style字符串末尾有一個\0結(jié)束符,也需要占一個char空間,因此sizeof("1") 返回2。而strlen返回的是字符數(shù),不包括\0結(jié)束符。
sizeof 無法獲取動態(tài)分配的內(nèi)存大小,即使用malloc動態(tài)的分配內(nèi)存,無法使用sizeof獲取其大小。