#include <stdio.h>
#include <string.h>
int main(void)
{
char ch='a';
printf("sizeof(ch) = %d\n", sizeof(ch));
printf("sizeof('a') = %d\n", sizeof('a'));
printf("sizeof('a'+'b'+'C') = %d\n", sizeof('a'+'b'+'C'));
printf("sizeof(\"a\") = %d\n", sizeof("a"));
}
该程序使用sizeof
来计算尺寸。为什么'a'
的大小与ch
(其中ch='a'
)的大小不同?
sizeof(ch) = 1
sizeof('a') = 4
sizeof('a'+'b'+'C') = 4
sizeof("a") = 2
答案 0 :(得分:51)
TL; DR -sizeof
适用于操作数的类型。
sizeof(ch)
== sizeof (char)
-------------------(1)sizeof('a')
== sizeof(int)
--------------------(2)sizeof ('a'+ 'b' + 'c')
== sizeof(int)
---(3)sizeof ("a")
== sizeof (char [2])
----------(4)让我们现在看看每种情况。
ch
被定义为char
类型,因此非常简单。
在C中,sizeof('a')
与sizeof (int)
相同,因为字符常量的类型为整数。
引用C11
,
一个整数字符常量的类型为
int
。 [...]
在C ++中,字符 literal 的类型为char
。
sizeof
是编译时运算符(当操作数是VLA时除外),因此使用表达式的类型。如前所述,所有整数字符常量的类型均为int
,因此int
+ int
+ int
产生int
。因此,操作数的类型为int
。
"a"
是由两个char
,'a'
和0
(空终止符)组成的数组(空终止符)(不,它不会衰减为指向数组类型第一个元素的指针),因此其大小与包含两个char
元素的数组的大小相同。
最后,sizeof
产生类型为size_t
的结果,因此您必须使用%zu
格式说明符来打印结果。
答案 1 :(得分:23)
在C中,'a'
是类型int
的常数。它不是{strong>不是一个char
。因此sizeof('a')
与sizeof(int)
相同。
sizeof(ch)
与sizeof(char)
相同。 (C标准保证'a'
形式的所有字母数字常量(以及其他一些常量)都可以放入char
中,因此char ch='a';
总是定义明确的。)
请注意,在C ++中,'a'
是类型为char
的文字; C和C ++之间还有另一个区别。
在C中,sizeof("a")
是sizeof(char[2])
,它是2。sizeof
不会促使数组类型的 decay 指向指针。
在C ++中,sizeof("a")
是sizeof(const char[2])
,它是2。sizeof
不会将数组类型的 decay 指示为指针。
在两种语言中,'a'+'b'+'C'
是一种int
类型,在C ++中是由于隐式提升了整数类型。
答案 2 :(得分:9)
首先,sizeof
的结果是类型size_t
,应使用%zu
格式说明符打印。忽略该部分,并假设int
是4个字节,则
printf("sizeof(ch) %d\n",sizeof(ch));
将在C中打印1,在C ++中打印1。
这是因为在两种语言中,每个定义都保证char
为1字节。
printf("sizeof('a') %d\n",sizeof('a'));
将在C中打印4,在C ++中打印1。
这是因为出于历史原因,字符文字在C中的类型为int
1),但是在C ++中它们的类型为char
,因为这是常识(和ISO 14882)规定。
printf("sizeof('a'+'b'+'C) %d\n",sizeof('a'+'b'+'C'));
将以两种语言打印4。
在C中,int + int + int
的结果类型自然是int
。在C ++中,我们有char + char + char
。但是+会调用implicit type promotion rules,所以无论如何我们最终都以int
结尾。
printf("sizeof(\"a\") %d\n",sizeof("a"));
将以两种语言打印2。
字符串文字"a"
在C中的类型为char[]
,在C ++中的类型为const char[]
。无论哪种情况,我们都有一个由a
和一个空终止符组成的数组:两个字符。
作为旁注,发生这种情况的原因是,对"a"
的操作数时,数组sizeof
不会衰减为指向第一个元素的指针。如果我们通过写sizeof("a"+0)
来引起数组衰减,那么我们将得到一个指针的大小(可能是4或8)。
1)在黑暗年代的某个地方,没有类型,并且您编写的所有内容都可以归结为int
。然后,当丹尼斯·里奇(Dennis Ritchie)开始一起为C制定某种事实上的标准时,他显然决定始终将字符文字提升到int
。然后,当C标准化时,他们说字符文字就是int
。
在创建C ++时,Bjarne Stroustrup意识到所有这些都没有多大意义,并且使字符文字应为char
类型。但是C委员会顽固地拒绝修复此语言缺陷。
答案 3 :(得分:2)
正如其他人提到的那样,C语言标准将字符常量的类型定义为int
。历史原因是C及其前身B最初是在具有各种字长的DEC PDP小型计算机上开发的,该微型计算机支持8位ASCII,但只能在寄存器上执行算术运算。早期的C版本将int
定义为机器的本机字大小,小于int
的任何值都需要扩展为int
才能传递给计算机。函数,或按位,逻辑或算术表达式使用,因为这就是底层硬件的工作方式。
这也是为什么整数提升规则仍将小于int
的任何数据类型提升为int
的原因。出于类似的历史原因,C实现也被允许使用一个补码数学而不是两个补码,并且字符转义默认为八进制和八进制常量的事实仅从0
开始,而十六进制需要\x
或0x
是那些早期的DEC小型计算机的字长可分为三字节的块,但不能分为四字节的半字节。
自动升级为int
只会造成麻烦。 (有多少程序员知道将两个uint32_t
表达式相乘是未定义的行为,因为某些实现将int
定义为64位宽,因此该语言要求比int
低的任何类型的秩都必须被提升为 signed int
,将两个int
被乘数相乘的结果为int
类型,该乘法会溢出一个有符号的64位乘积,并且是未定义的行为?)但这就是C和C ++坚持使用它的原因。
答案 4 :(得分:0)
我假设代码是用C编译的。
在C语言中,'a'
被视为int
类型,而int
的大小为4。
在C ++中,'a'
被视为char
类型,如果尝试在cpp.sh中编译代码,它将返回1。