首先我们进行一个实验:
char str[] = "asdfg";
char *pstr = "asdfg";
std::cout << sizeof(str) << " " << sizeof(pstr);
得到的结果是: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
我们发现只有直接引用数组名的时候,得到的size才是数组的大小
为什么会这样呢?
- 我们经常说数组名就是指针,其实不太严谨。数组名和普通的指针有一些不一样。数组名是一个常量指针,我们不可以改变其值。
- 在某些情况下其语义会发生改变,比如
sizeof(name_of_array)
的时候,数组名代表的是一个数组,因此我们可以得到数组的大小 - 对数组名取地址也是合法的
std::cout << arr<<" "<<&arr;
得到的结果是一样的:
但是普通的指针:
int b = 10;
int* a = &b;
std::cout << a << " " << &a<<" ";
这两个的结果是不同的:
-
在函数的参数传递过程中,地址常量可以退化成对应的指针
就比如size2(int a[])
函数一样,数组名不再代表数组,而是转换为普通的指针,指针(32位下)占4个Byte
4.3更新:
如果sizeof的对象是函数,则返回函数返回值类型大小;
并且不会去执行函数;
同理如果sizeof的对象是表达式,也是返回表达式结果的类型大小,而不执行表达式。注意c_style字符串末尾有一个\0结束符,也需要占一个char空间,因此sizeof("1") 返回2。而strlen返回的是字符数,不包括\0结束符。
sizeof 无法获取动态分配的内存大小,即使用malloc动态的分配内存,无法使用sizeof获取其大小。