通常字符串文字是const char []的类型。但是当我把它视为其他类型时,我得到了奇怪的结果。
unsigned char *a = "\355\1\23";
使用此编译器抛出警告说“初始化中的指针目标在签名方面不同”,这是非常合理的,因为可以丢弃符号信息。
但随着以下
unsigned char b[] = "\355\1\23";
完全没有警告。我认为应该有一个警告,出于同样的原因。这怎么可能?
仅供参考,我使用的是GCC 4.8.4版。
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“简单分配”适用。
第一个是指针的初始化,目标类型的指针必须在签名上达成一致。
第二个是数组的初始化。使用字符串文字初始化的特殊规则使得文字的每个字符的值用于初始化数组的各个元素。
顺便说一句,除了你陈述之外,字符串文字不是用C语言限定的const
。你没有权利修改它们,但这并没有反映在类型中。