【问题标题】:Initializing the string in C; Is the following useful?在 C 中初始化字符串;以下有用吗?
【发布时间】:2021-09-07 06:36:01
【问题描述】:

我知道如何用两种不同的方式在 C 中初始化字符串。

char str[] = "abcd";

char str[] = {'a','b','c','d','\0' };

显然写"abcd" 而不是{'a','b','c','d','\0' } 既省时又舒适。

有什么特别的原因可以像最后一行那样初始化字符串吗?它在某些情况下有用还是多余?

【问题讨论】:

  • 不,没有意义。您显示的两条线严格等效。
  • 第二种形式适用于任何聚合初始化。第一种形式是 char 数组的特殊形式
  • 在这种情况下它们是等价的,但是你不能这样做 char* str = {'a','b','c','d','\0' }; 但你可以这样做 char* str = "abcd"; 因为后者首先创建一个未命名的数组,然后将 str 指针分配给它,而前者只是等待初始化为数组的字符列表。
  • 您的意思是“使用它没有意义吗?”还是“提供它的语言没有意义吗?”?语言提供它并不是毫无意义的,因为它显然是初始化任何类型数组的普通和通用方法。初始化一个真正的字符串是否有用取决于你。 (我,我很少使用它。)

标签: c string initialization


【解决方案1】:

一般来说,没有区别。除了一些高级例外,如下...

  • 在某些情况下,您需要一个不是有效 C 字符串的字符数组——也就是说,不是以 null 结尾的。那么必须使用后一种形式。不过,只有一些非常特殊的情况需要此类字符串:非常古老的 Unix 代码和某些嵌入式系统实现。

  • 后一种形式的另一个优点是更好的转义序列。字符串文字的转义序列有点损坏。假设我希望打印一个代码为 0xAA 的扩展符号,然后是字符串“ABBA”。 puts("\xAAABBA"); 不会编译,因为它将 \x 后面的所有内容都作为十六进制。 char str[] = {'\xAA','A','B','B','A','\0'}; puts(str); 工作正常。 (但是,您也可以将字符串文字拆分为多个,以实现相同的效果:"\xAA" "ABBA"。)

  • 使用字符串字面量进行初始化也存在此处讨论的微妙但严重的 C 语言缺陷:
    Inconsistent gcc diagnostic for string initialization

【讨论】:

  • 为了兼容性而引入的另一个语言缺陷是这个:char *s = "hello";
【解决方案2】:

char str[] = {'a','b','c','d','\0' } 形式很少用于初始化真正的字符串,这是真的。

我曾经写过一些代码来从生成的文本中过滤掉意外的淫秽词,并且出于自我审查的需要,我初始化了要查找的词数组,以一种不会冒犯任何未来维护的眼睛的方式程序员:

char badwords[][5] = {
    { 's', 0x68, 105, 0164, '\0' },
    { 'p', 0151, 0x73, 115, '\0' },
    { 'c', 117, 0156, 0x74, '\0' },
    { 'f', 0x75, 0143, 107, '\0' },
    /* ... */
};

【讨论】:

  • 通过混合八进制、十进制和十六进制来进一步混淆它的额外点。 :-)
  • @SteveSummit:抱歉这么明确,非 ASCII 字符集的可移植性如何?我想不出任何简单的方法来达到同样的混淆程度。
  • @chqrlie 不用担心——当然,我只是在开玩笑。也许我应该为没有认真对待您的问题而道歉!我也想不出任何简单的事情——我能想到的最好的办法是解密任何大写字母,就像Caesar,注意避开 EBCDIC 中的不连续性。也就是说,类似于char badwords[] = { "shiW", "piVs", "cXnW", "fXFk"},在运行时使用基于if(isupper(*p) *p = tolower(*p-3) 的东西进行解码。 (或者也许只使用 rot13。)
  • @TedLyngmo 我不能声称功劳——我从 Sjörd Mullender 在First Annual IOCCC 的获奖作品中窃取了这个想法。
  • @SteveSummit:这可行,但仍然不能移植到所有潜在的字符集......如果在运行时解码是可以的,那么一个简单的排列可能就可以了。无论哪种情况,都不再是 OP 问题的说明 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 2011-05-02
  • 2012-12-03
  • 2022-01-16
相关资源
最近更新 更多