在 C11 中,字符串文字为 char[]、unsigned char[]、char* 和 unsigned char*
Posted
技术标签:
【中文标题】在 C11 中,字符串文字为 char[]、unsigned char[]、char* 和 unsigned char*【英文标题】:In C11, string literals as char[], unsigned char[], char* and unsigned char* 【发布时间】:2017-12-21 11:10:09 【问题描述】:通常字符串字面量是 const char[] 类型。但是当我把它当作其他类型时,我得到了奇怪的结果。
unsigned char *a = "\355\1\23";
使用此编译器会抛出警告说“初始化中的指针目标的符号不同”,这是非常合理的,因为可以丢弃符号信息。
但有跟随
unsigned char b[] = "\355\1\23";
根本没有警告。我认为应该出于上述相同原因发出警告。这怎么可能?
仅供参考,我使用的是 GCC 版本 4.8.4。
【问题讨论】:
在询问有关 C 的问题时,请始终包含 C 标签,否则人们将找不到问题。除非您的问题是与 C11 相关的功能,否则您不应使用 C11 标签。如果是这样,请结合 C 和 C11 标签。我已经修复了帖子。 【参考方案1】:C 中字符串字面量的类型为char[]
,衰减为char*
。请注意,C 与 C++ 不同,它们的类型为 const char[]
。
在第一个示例中,您尝试将char*
分配给unsigned char*
。这些不是兼容的类型,因此您会收到编译器诊断消息。
在第二个示例中,以下内容适用,C11 6.7.9/14:
字符类型的数组可以由字符串字面量或 UTF-8 字符串初始化 字面量,可选地用大括号括起来。字符串文字的连续字节(包括 如果有空间或数组大小未知,则终止空字符)初始化 数组的元素。
表示代码与此相同:
unsigned char b[] =
'\355',
'\1',
'\23',
'\0'
;
这也可能产生警告,但它是有效的代码。当涉及到不同整数类型之间的赋值1 时,C 具有宽松的类型安全性,但在涉及指针类型之间的赋值时要严格得多。
出于同样的原因,我们可以写成unsigned int x=1;
而不是unsigned int x=1u;
。
附带说明一下,我不知道您希望使用值为 355 的八进制转义序列实现什么。也许您打算写 "\35" "5\1\23"
?
1 初始化的类型规则与赋值相同。 6.5.16.1 “简单赋值”适用。
【讨论】:
我想处理 RAW 图像的字节流。在原始代码中,我使用了 \377。【参考方案2】:首先是指针的初始化,指针的目标类型必须在签名上一致。
第二个是数组的初始化。使用字符串字面量进行初始化的特殊规则是,采用字面量的每个字符的 value 来初始化数组的各个元素。
顺便说一句,除了您说的以外,字符串文字在 C 中不是 const
限定的。您无权修改它们,但这不会反映在类型中。
【讨论】:
以上是关于在 C11 中,字符串文字为 char[]、unsigned char[]、char* 和 unsigned char*的主要内容,如果未能解决你的问题,请参考以下文章
为啥仅在某些情况下才能将字符串文字隐式转换为 char* ? [复制]