C中的字符[重复]

Posted

技术标签:

【中文标题】C中的字符[重复]【英文标题】:Characters in C [duplicate] 【发布时间】:2015-12-11 16:05:17 【问题描述】:

我在 C 中有这段代码:

#include<stdio.h>
int main()

    char ch='17 December 2008';
    printf("%c",ch);

我期望它应该报告一个错误,但它显示“8”作为输出。 谁能解释一下原因?

【问题讨论】:

你的编译器警告告诉你什么? 你用的是什么编译器? 代码块和Dev C++ 启用编译器警告。 @Kerrek-警告它显示-字符常量对于它的类型来说太长了 【参考方案1】:

标准说:

包含多个字符(例如,'ab')的整数字符常量的值,或包含不映射到单字节执行字符,由实现定义。

实现必须记录每个实现定义的行为,因此如果您想确切了解它的作用,则必须查阅实现随附的文档。可以在here 中找到与您的特定实现相关的文档。引用:

编译器一次计算一个字符的多字符字符常量,将前一个值左移每个目标字符的位数,然后在截断到宽度的新字符的位模式中进行或运算的目标人物。最后的位模式给定类型int,因此是有符号的,无论单个字符是否有符号(与 GCC 3.1 及更早版本略有不同)。如果常量中的字符多于目标 int 中的字符数,编译器会发出警告,并忽略多余的前导字符。

例如,对于具有 8 位字符的目标,'ab' 将被解释为 ‘(int) ((unsigned char) 'a' * 256 + (unsigned char) 'b')’,而 '\234a' 将被解释为 ‘(int) ((unsigned char) '\234' * 256 + (unsigned char) 'a')’.**

【讨论】:

【参考方案2】:

这是一个多字符文字。

包含多个 c-char 的普通字符文字是 多字符文字。多字符文字的类型为 int 和 实现定义的值

同样来自 C11 规范中的 6.4.4.4/10:

整数字符常量的类型为 int。整数的值 包含单个字符的字符常量,该字符映射到 单字节执行字符是 映射字符的表示解释为整数。这 包含多个字符的整数字符常量的值 字符(例如,'ab'),或包含字符或转义序列 不映射到单字节执行字符,是 实现定义。如果一个整数字符常量包含一个 单个字符或转义序列,其值是结果 当一个 char 类型的对象的值是单 字符或转义序列转换为 int 类型。

如果你这样做,你会得到:

char ch='17 December';
printf("%c",ch);

输出:

r

而且,为此,你得到:

char ch='17 December 2008';
printf("%c",ch);

输出:

8

它出现在您的系统上,最不重要的8 bits 用于分配 到ch。因为您的字符文字是恒定的,所以这很可能 在编译时发生:(例如,当我编译时发生以下情况 使用 gcc)

请记住,单引号字符常量的类型是 int,但您将其分配给 char,因此必须将其截断为单个字符。

'a' 的类型例如是int in C。 (不要与'a' 混淆 C++ which is a char。另一方面,'ab' 的类型在两个 C 中都是 int 和 C++。)

现在,当您将此 int 类型分配给 char 类型并且值大于 char 可以表示的值时,需要进行一些挤压以使结果适合更宽的类型 char 并且实际结果是实现定义。

【讨论】:

为什么它需要最右边的字符而不是最左边的? 为什么它需要最右边的字符而不是最左边的?”是一个无意义的问题,因为您只能使用一个 char 常量初始化一个 char 变量。如果编译器会采用中间字符,那也很好。编译器应该并且可能会给出错误/警告消息,您应该听听。 由于行为是实现定义的,所以这个推理只适用于这个特定的平台。其他平台可能会做一些不同的事情。【参考方案3】:

Gcc 也是如此。 8 是右引号之前的最后一个字符。

C99 说:

包含多个字符的整数字符常量的值(例如, 'ab'),或包含不映射到单字节的字符或转义序列 执行字符,是实现定义的。

您收到的警告与您分配给它的类型有关,而不是表达式本身。例如:

int i = '2008';
printf("%d\n", i);

不会产生警告并且是合法的:

整数字符常量是包含一个或多个多字节字符的序列 在单引号中,如“x”。宽字符常量是相同的,除了前缀 字母 L。除了稍后详述的少数例外,序列的元素是任何 源字符集的成员;它们被映射到实现定义的 方式给执行字符集的成员。

错误:

一个整数字符常量包括多个字符或一个宽字符 常量包含多个多字节字符

也出现在标准中。

为什么选择了最后一个字符

但编译器各不相同,部分原因在于编译器选择对机器的序列和字节序进行编码的方式。查看答案:Multiple characters in a character constant。

【讨论】:

以上是关于C中的字符[重复]的主要内容,如果未能解决你的问题,请参考以下文章

C中的反向字符串[重复]

关于C中的指针和字符串的问题[重复]

Vector中的C ++字符串输入[重复]

反转字符串c ++中的单词[重复]

Java中的字符不会随后增量更新[重复]

For循环问题中的PHP字符迭代[重复]