Sac*_*tre 5 c c++ size operating-system
在一次采访中我问过这个问题,char在某些操作系统中大小为2个字节,但在某些操作系统中它是4个字节或不同.
为什么会这样?
为什么它与其他基本类型不同,例如int?
这可能是一个棘手的问题.的sizeof(char)是总是 1.
如果大小不同,可能是因为编译器不合规,在这种情况下问题应该是关于编译器本身,而不是关于C或C++语言.
1 sizeof运算符产生其操作数的对象表示中的字节数.操作数是表达式(未计算)或带括号的type-id.sizeof运算符不应该应用于具有函数或不完整类型的表达式,或者在声明所有枚举数之前应用于枚举类型,或者应用于此类型的带括号的名称,或者应用于指定位字段的左值.
sizeof(char),sizeof(signed char)和sizeof(unsigned char)是1施加到任何其他基本类型(3.9.1)的sizeof的结果是实现定义的.(强调我的)
除指出的类型之外的其他类型的大小是实现定义的,并且它们因各种原因而变化.一个int具有如果它在64位的而不是32位的表示范围更好,但它也可以作为一个32位体系结构32位更有效.
类型的物理大小(就位数而言)通常由目标硬件决定.
例如,某些CPU只能以不小于16位的单位访问内存.为获得最佳性能,char可以定义一个16位整数.如果你想在这个CPU上使用8位字符,编译器必须生成额外的代码,用于将8位值打包到16位存储单元和从16位存储单元中解压缩.额外的打包/解包代码将使您的代码更大更慢.
这不是它的结束.如果将16位存储器单元细分为8位字符,则可以有效地在地址/指针中引入一个额外的位.如果CPU中的普通地址是16位,那么你在哪里添加额外的第17位?有两种选择:
后一种选择有时可行.例如,如果整个地址空间被分成两半,其中一个由内核使用,另一个由用户应用程序使用,则应用程序指针将永远不会在其地址中使用一位.您可以使用该位选择16位存储器单元中的8位字节.
C被设计为在尽可能多的不同CPU上运行.这就是为什么的物理尺寸char,short,int,long,long long,void*,void(*)(),float,double,long double,wchar_t,等可以有所不同.
现在,当我们在不同的编译器中讨论不同的物理尺寸,为同一个CPU生成代码时,这就变成了一种随意的选择.但是,它看起来可能不是那么随意.例如,Windows的许多编译器定义int= long= 32位.他们这样做是为了避免程序员在使用期望INT= LONG= 32位的Windows API时产生混淆.由于失去了程序员的注意力,定义int和long其他东西会导致错误.因此,编译器必须在这种情况下效仿.
最后,C(和C++)标准使用chars和bytes.它们在尺寸方面是相同的概念.但是C的字节不是典型的8位字节,它们可以合法地大于前面解释的那些字节.为避免混淆,您可以使用该术语octet,其名称代表数字8.许多协议使用此词来实现此目的.