在 C 中,为啥 sizeof(char) 为 1,而 'a' 是 int?

Posted

技术标签:

【中文标题】在 C 中,为啥 sizeof(char) 为 1,而 \'a\' 是 int?【英文标题】:In C, why is sizeof(char) 1, when 'a' is an int?在 C 中,为什么 sizeof(char) 为 1,而 'a' 是 int? 【发布时间】:2011-01-16 03:49:36 【问题描述】:

我试过了

printf("%d, %d\n", sizeof(char), sizeof('c'));

并得到 1, 4 作为输出。如果一个字符的大小是 1,为什么'c' 给我 4?我想这是因为它是一个整数。因此,当我执行char ch = 'c'; 时,是否会发生隐式转换,在将其分配给 char 变量时,从 4 字节值到 1 字节值?

【问题讨论】:

我相信这与自动整数提升有关,事实多于相信的人会发布事实答案 @Roger:他问的是 C 和 C++ sizeof('a') 之间的区别,而我问是否发生了转换?请参阅问题正文。我已经推断出 'a' 是 C 中的一个整数。 我要感谢“David Rodríguez - dribeas”指出我的答案中的链接不正确。我正在删除我的答案。 legends2k,在我看来,正确的答案应该是 Peter 或 Neil。 你得到了答案,但有一条评论:你不能用"%d" 打印size_t 对象。由于sizeof 产生size_t 一个size_t 对象,您应该使用"%zu" (C99) 打印它或将其转换为unsigned long 并使用"%lu" (C89) 打印。 ***.com/questions/433895/… 【参考方案1】:

根据 ANSI C 标准,在使用整数的上下文中,char 被提升为 int,您在 printf 中使用了整数格式说明符,因此值不同。一个 char 通常是 1 个字节,但它是基于运行时和编译器定义的实现。

【讨论】:

整数格式指的是 sizeof('a') 而不是 'a' 所以我看不出这个论点是如何成立的。 C 标准说 char 文字是 int 类型 - 它有 sizeof int 并且不涉及提升。 您的回答似乎表明 C 编译器在编译程序时会检查库函数使用的格式字符串,您确定是这样吗? 如果是 scanf("%s\n",format) ; printf(格式, sizeof(char), sizeof('a'));并且您会在出现提示时输入“%d, %d\n”?在这种情况下,编译器无法先验地知道变量类型,而不得不盲目地使用省略号运算符? @Peter van der Heijden :你是对的,格式字符串及其说明符与在它们之后传递的变量的类型无关。 gcc,如果它们不对齐,将发出警告,但它可以使用不匹配的类型进行编译,假设您比编译器知道的更多。也就是说,“a”在 sizeof 中,而不是在“整数上下文”中。 sizeof 调用返回 size_t,我相信它通常被 typedef 为无符号整数。【参考方案2】:

在 C 中,'a' 是一个整数常量 (!?!),因此 4 对您的架构是正确的。它被隐式转换为 char 以进行赋值。根据定义,sizeof(char) 始终为 1。标准没有说明单位 1 是什么,但通常是字节。

【讨论】:

+ 1 表示“但通常是字节”,我还在笑:) 标准将sizeof 运算符定义为以字节 为单位返回大小,因此它不是经常,而是总是。在“sizeof 运算符”的第二段中:“sizeof 运算符产生其操作数的大小(以字节为单位)。” 在阅读 SO 帖子中的“隐式投射”时,我总是不寒而栗。没有隐式转换:转换始终是显式转换。 C 标准在 6.3 中说:“几个运算符自动将操作数值从一种类型转换为另一种类型。本子条款规定了这种隐式转换所需的结果,以及强制转换操作所产生的结果( 显式转换)。”。你想说“隐式转换”。 sizeof() 以 CHAR_BITS 的(整数,我相信)倍数衡量。不多也不少。 sizeof(char) == 1,根据定义。另一种类型的位数可以通过将 sizeof(type) 与 CHAR_BITS 相乘来确定。当然,大多数(如果不是全部)平台的 CHAR_BITS 为 8。 总是字节。它可能不是八位字节。【参考方案3】:

这在 ISO C11 6.4.4.4 Character constants 中有所涵盖,尽管它与早期的标准基本没有变化。这在/10 段中指出:

整数字符常量的类型为 int。整数字符常量的值 包含映射到单字节执行字符的单个字符是 映射字符表示的数值,解释为整数。

【讨论】:

+1 感谢您引用标准;我想知道为什么选择 integer character constant 而不是 character constant【参考方案4】:

这是sizeof 运算符的正常行为(参见Wikipedia):

对于数据类型,sizeof 返回数据类型的大小。对于char,你得到 1。 对于表达式,sizeof 返回变量或表达式类型的大小。当字符文字输入为 int 时,您会得到 4。

【讨论】:

【参考方案5】:

C 标准规定,像 'a' 这样的字符文字是 int 类型,而不是 char 类型。因此(在您的平台上)它的 sizeof == 4。请参阅 this question 以获得更全面的讨论。

【讨论】:

我询问了两种数据类型之间发生的提升/转换,而讨论/答案没有回答这个问题。 @legends2K 你问“如果一个字符的大小是 1,为什么 'c' 给我 4?”正如这个答案和我链接的问题所解释的那样,'a' 的 sizeof == 4,显然没有进行任何演员或促销活动。 好吧。在它下面有一个详细的问题形式,上面写着“当它被分配给 char 变量时,是否存在从 4 字节值到 1 字节值的隐式类型转换”。我相信这也是其中的一部分。 没有推广。在 C 中,'a' 的类型为 int。在大多数 C 实现中,'a' 与 97 完全相同。在 C++ 中,'a' 具有 char 类型。

以上是关于在 C 中,为啥 sizeof(char) 为 1,而 'a' 是 int?的主要内容,如果未能解决你的问题,请参考以下文章

c语言中,为啥在64位系统中long跟指针的大小是8,而32位的却是4?是啥导致不一样?求详细解答

为啥这个 sizeof(c+a) 给出 4 字节而不是 3

C语言 数组的问题,书上的例子,说a = sizeof(mu) / sizeof(mu[0])可以统计数组的元素个数,为啥?

C语言中sizeof的用法

为啥 C++0x 中有 sizeof... 运算符?

为啥从字符串常量转换为 'char*' 在 C 中有效但在 C++ 中无效