C 字符数组初始化困境

C 字符数组初始化困境,c,arrays,initialization,initializer,C,Arrays,Initialization,Initializer,考虑以下代码: // hacky, since "123" is 4 chars long (including terminating 0) char symbols[3] = "123"; // clean, but lot of typing char symbols[3] = {'1', '2', '3'}; 因此,扭曲实际上是在代码注释中描述的,有没有一种方法可以使用字符串文字初始化char[],而不终止于零 更新:看起来IntelliSense是错误的。事实上,这种行为在C标准中

考虑以下代码:

// hacky, since "123" is 4 chars long (including terminating 0)
char symbols[3] = "123";

// clean, but lot of typing
char symbols[3] = {'1', '2', '3'};
因此,扭曲实际上是在代码注释中描述的,有没有一种方法可以使用字符串文字初始化
char[]
,而不终止于零


更新:看起来IntelliSense是错误的。事实上,这种行为在C标准中是明确定义的。

如果数组只有3个字符长,则第一行代码与第二行代码相同。字符串末尾的
'\0'
将不会被存储。瞧,它没有什么“脏”或“错”。

1)你提到的问题不是问题。 2) 问:有没有一种方法可以在不终止零的情况下用字符串文字初始化char[]您已经在这样做了。

这个

char symbols[3] = "123";
这是一个有效的声明

根据1988年的ANSI C规范:

字符类型的数组可以由字符串初始化 文字,可以选择用大括号括起来。连续字符 字符串文字(包括终止的空字符,如果 存在空间或阵列大小未知时)初始化 数组的成员

因此,你所做的技术上是好的

请注意,字符数组是初始值设定项上所述约束的例外:

初始值设定项列表中的初始值设定项不得超过 是要初始化的对象

然而,一段代码的技术正确性只是该代码“优点”的一小部分。行
char符号[3]=“123”
会立即让资深程序员感到可疑,因为它表面上看起来是一个有效的字符串初始化,以后可能会被这样使用,导致意外错误和一定的死亡

如果你想走这条路,你应该确定这是你真正想要的。保存那个额外的字节不值得为此而麻烦。空符号(如果有的话)允许您编写更好、更灵活的代码,因为它提供了一种明确的(在大多数情况下)终止数组的方法

(规范草案可用。)

为了在本页其他地方补充鲁迪的意见,C99规范草案第32个示例在§6.7.8(第130页)中指出:

char s[] = "abc", t[3] = "abc";
与相同

char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
从中你可以推断出你想要的答案


可以找到C99规范草案。

浪费这一个字节真的很糟糕吗?第一行怎么了?如果您想要一个字符数组,而不是以null结尾的字符串,那么只需使用它来初始化数组。在它旁边放一条注释以指示您正在执行的操作。@nmichaels否,但有一些遗留代码要求对数组应用了此类限制。@Praetorian我不确定第一个变量是否正确,因为IntelliSense正在产生错误,例如:IntelliSense:type“const char[16]”的值不能用于初始化type的实体“Byte[15]”@Petr Abdulin:那么,我错误地认为初始化时使用的字符串比您试图将其放入的数组大。对此表示抱歉。我不确定第一个变量是否正确,因为IntelliSense正在产生错误,例如:IntelliSense:类型为“const char[16]”的值不能用于初始化类型为的实体字节[15]“参见C99文档,§6.7.8,第32点(示例8),其中说:
chart[3]=“abc”
t[]={'a','b','c'}相同;
。现在IntelliSense是VC++,我听说VC++还不做C99,但在旧标准IIRC中也是一样。@Rudy Velthuis:+1表示C99引用。好吧,C允许我们做很多事情,比如写未分配的内存,但这是否意味着这是一种正确的方法?它正在工作,是的,我只是想确定这段代码是正确的,或者可能不是。@Petr Abdulin:你刚才说的似乎不相干我试图回答你提出的问题。事实上,我的问题并不完全正确(我实际上是在问代码的正确性),但无论如何,谢谢。谢谢Richard的标准参考,现在我可以睡个好觉了:-)。至于其余的,最后的结构实际上是一个三维数组,带有一个类似于地图的数据,它是用字符初始化的。所以不允许空终止字符。如果数组以后用作字符串,这确实是可疑的。否则,失败的终止符不应产生任何影响。例如,音乐或图形文件(如Windows.bmp文件或.tiff文件)的某些文件头包含2或4个字符的“标记”“识别其标题信息的一部分。+1表示书面回答良好。FWIW,它是
Rudy
,而不是
Rudi
。C这样做的问题是,它要求您显式地声明字符串的长度<代码>字符s[3]=“abc”是有效的,但是如果您以后决定只需要“ab”,则必须将大小从3更新为2。如果您忘记了,
chars[3]=“ab”仍然有效,但它包含尾随的“\0”。没有真正好的方法来解决这个问题,除非您使用某种工具为您生成声明(不,C预处理器的功能不足以完成此任务)。如果我要重新设计语言,我可能会添加一种新形式的字符串文字,它不指定尾随“\0”。很抱歉,@Rudy。我修好了。