sizeof本身是C语言的一个运算符,但也被C++支持,且很多C++代码中经常会出现。
sizeof可以很容易计算一个数组的长度,这在数组作为参数的函数中很有用(数组作为函数参数,传入的其实是首元素的地址,必须带上数组的实际长度作为另一个参数才行)。
请看下面代码(visual stadio 2019环境编译,unicode字符集,x64程序):
#include <iostream>
int main()
{
using namespace std;
int iValue = 10;
cout << "int:" << sizeof(iValue) << endl;
int array_int[] = { 1, 2, 3 };
cout << "array_int:" << sizeof(array_int) << endl;
char chChar = 'a';
cout << "char:" << sizeof(chChar) << endl;
char array_char[] = { 'a', '是', 'c' };
cout << "array_char:" << sizeof(array_char) << endl;
wchar_t wcChar = L'a';
cout << "wchar:" << sizeof(wcChar) << endl;
wchar_t array_wchar[] = { L'a', L'是', L'c' };
cout << "array_wchar_t:" << sizeof(array_wchar) << endl;
const char* pEnglish = "hello";
cout << "char*_en:" << sizeof(pEnglish) << endl;
const char* pChinese = "中文";
cout << "char*_zh:" << sizeof(pChinese) << endl;
int* pInt = new int(10);
cout << "int*:" << sizeof(pInt) << endl;
system("pause");
return 0;
}
首先,编译时便会有一下警告:
问题出在这一句:char array_char[] = { 'a', '是', 'c' };
为何会有警告?这里涉及到另一个编码问题,此处先不说,后面有机会再写一篇文章说明。
执行结果如下:
是否有些意外?逐行解释:
sizeof(iValue)输出4很简单,一个int占4个字节,都会背了。
sizeof(array_int)输出12,说明sizeof的参数如果是数组,则会输出数组中所有元素的总字节数。3个int元素,每个int4个字节,一共12个字节,很好理解。
后面的char和array_char也证明了这一点,一个char占一个字节,array_char里有3个元素,每个占1个字节,这个数组中加起来就是3个字节。
wchar_t是宽字节,其对应的所有字符都是两个占2个字节。所以sizeof(array_wchar)就会输出3*2=6。
sizeof(pEnglish)为何会输出8呢?这是因为sizeof的参数若不是数组,只是计算其对应变量的字节数。这行代码输出的其实是pEnglish这个变量的字节数,而不是它所指向的字符串。pEnglish是什么?是个指针。在64位程序中,不管什么类型的指针,都是占8个字节;而在32位程序中,指针占4个字节。
sizeof(pChinese)中pChinese所指向是一个中文字符串,但是pChinese本身也是一个char类型的指针,所以会输出8。
sizeof(pInt),pInt也是一个指针,所以输出的还是8(这里没有delete pInt,实际程序中一定不能忘了)。
总结起来两点:
1、sizeof的参数如果是数组,则输出数组中所有元素的字节总数;
2、sizeof的参数如果不是数组,则输出参数本身所占的字节数。
根据上面所讲第一点,很容易计算出数组中元素的个数:数组中所有元素的总字节数/数组元素类型的字节数。
例如上面的array_int,则只需要:sizeof(array_int)/sizeof(int);array_wchar,则只需要sizeof(array_wchar)/sizeof(wchar_t)即可。
另外,上面说到,在32位程序中,指针变量本身占4个字节,以上程序,在vs的配置管理器中将程序改成x86的即可验证。
运行结果如下:
可以看到,后面四个指针变量的sizeof都是4。
除了这些,我们还经常听到“一个英文字符占1个字节,一个中文字符占2个字节”,又是什么意思呢?在另一篇文章中会有介绍。