首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sizeof与chars的混淆行为

sizeof与chars的混淆行为
EN

Stack Overflow用户
提问于 2018-07-04 20:41:27
回答 4查看 3K关注 0票数 44
代码语言:javascript
复制
#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')的大小不同?

代码语言:javascript
复制
sizeof(ch)          = 1
sizeof('a')         = 4
sizeof('a'+'b'+'C') = 4
sizeof("a")         = 2
EN

回答 4

Stack Overflow用户

发布于 2018-07-04 20:43:28

TL;DR - sizeof处理操作数的类型。

  • sizeof(ch) sizeof (char)-------------------(1)
  • sizeof('a') --------------------(2)
  • sizeof ('a'+ 'b' + 'c') ---(3)
  • sizeof ("a") ----------(4)

== == sizeof(int) == sizeof(int) == sizeof (char [2])

现在让我们看看每个案例。

  1. ch被定义为char类型,所以非常简单。
  2. 在C中,sizeof('a')sizeof (int)相同,因为字符常量的类型为整数。

引用C11的话,

整数字符常量的类型为int。...

在C++中,字符文本的类型为char

  1. sizeof是编译时运算符(操作数是VLA时除外),因此使用表达式的类型。与前面一样,所有整数字符常量都是int类型,因此int + int + int会生成int。因此,操作数的类型被认为是由两个空终止符( 'a'0 )组成的数组(不,它不会衰减为指向数组类型的第一个元素的指针),因此其大小与具有两个char元素的数组的大小相同。

也就是说,最后,sizeof会生成size_t类型的结果,因此必须使用%zu格式说明符来打印结果。

票数 51
EN

Stack Overflow用户

发布于 2018-07-04 20:43:11

在C中,'a'int类型的常量。It is a 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不会引起数组类型向指针的衰减。

在C++中,sizeof("a")sizeof(const char[2]),它是2。sizeof不会引起数组类型向指针的衰减。

在这两种语言中,由于整型类型的隐式提升,'a'+'b'+'C'在C++中是一种int类型。

票数 23
EN

Stack Overflow用户

发布于 2018-07-05 07:52:07

正如其他人所提到的,C语言标准将字符常量的类型定义为int。其历史原因是C及其前身B最初是在具有各种字长的DEC PDP小型机上开发的,这些小型机支持8位ASCII,但只能在寄存器上执行算术运算。C的早期版本将int定义为机器的原生字长,并且任何小于int的值都需要扩展为int,以便传递到函数或从函数传递,或者用于按位、逻辑或算术表达式,因为这是底层硬件的工作方式。

这也是整数提升规则仍然规定将小于int的任何数据类型提升为int的原因。由于类似的历史原因,C实现也被允许使用一补数学而不是二补数学,并且字符转义默认为八进制和八进制常量仅以0开头,而十六进制需要\x0x的事实是,那些早期的DEC小型机的字长可分为三字节块,而不是四字节半字节。

如今,自动升级到int只会带来麻烦。(有多少程序员知道将两个uint32_t表达式相乘是未定义的行为,因为一些实现将int定义为64位宽,该语言要求任何比int更低的等级类型必须提升为带符号的int,两个int被乘数相乘的结果具有类型int,该乘法可以溢出有符号的64位乘积,这是未定义的行为?)但这就是C和C++坚持使用它的原因。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51173976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档