【问题标题】:Is '\0' guaranteed to be 0?'\0' 是否保证为 0?
【发布时间】:2011-09-25 22:54:17
【问题描述】:

我用 C 写了这个函数,它的目的是遍历一个字符串到下一个非空白字符:

char * iterate_through_whitespace(unsigned char * i){
    while(*i && *(i++) <= 32);
    return i-1;
}

它似乎工作得很好,但我想知道在*i == '\0' 的情况下假设*i 将被评估为false 是否安全,并且它不会在结束后迭代细绳。它在我的计算机上运行良好,但我想知道它在其他机器上编译时是否会表现相同。

【问题讨论】:

  • 好问题。更多的人应该在假设之前问自己。 Triva:当你对一个 UTF8 字符串进行空终止时会发生什么?在双/三/四字节领导者之后?在 UCS-16 中?那么终止符是两个字节,还是 UNICODE 不推荐使用零终止符?
  • @sehe:空终止符对 UTF-8 字符串正常工作。对于 UCS-2 或 UTF-16(不是 UCS-16),空终止符是 16 位。
  • @Keith:您的观点是正确的,但不完整。 UTF-8 字符串在部分字符后具有空终止符是格式错误的,并且在使用标准库函数转换时遇到空字节时将导致 EILSEQ
  • @R..:那么我认为它不是 UTF-8 字符串。对于像strcpy() 这样的非转换函数,它不会导致EILSEQ 错误。不过,好点。 (而且最初的发帖人可能会忽略这些细节,至少现在是这样。)

标签: c nul


【解决方案1】:

标准说:

应该存在一个所有位都设置为 0 的字节,称为空字符 在基本执行字符集中;它用于终止一个 字符串。

【讨论】:

  • 所有位都设置为 0 的字节的值为 0。这似乎很明显,而且确实如此,但您必须在标准中进行一些搜索才能证明这一点。
  • @Keith Thompson 我正在寻找更强有力的断言,但我似乎找不到任何真正相关的东西。
  • 我认为看到了一个更正,确保将 a 和 int 设置为 0 会产生 0 值,但我找不到 oit。
  • 你必须深入了解C99 6.2.6.2,它涵盖了整数类型的表示。它需要一个二进制表示(它定义)并表示字符类型没有填充位。
  • @Artefacto: N1256 6.2.6.2p5 -- 但是字符类型需要缺少填充位,因此这些类型没有必要。
【解决方案2】:

是的——但在我看来,更明确的风格更好:

while (*i != '\0' && ...

但与32 进行比较并不是最好的方法。 32 恰好是空格字符的 ASCII/Unicode 代码,但 C 不保证任何特定的字符集——并且有很多值小于 32 的控制字符不是空格。

使用isspace() 函数。

(而且我永远不会命名指针i。)

【讨论】:

  • +1 谢谢!我从来没有对 isspace() 函数感到陌生。我会用它。 i 是迭代器的缩写,我经常用。
  • @PaulPRO: i 往往是整数的缩写。
  • @PaulPRO:在 C++ 中,我认为it 是迭代器的通用名称。
  • 你确定吗?我经常将i 视为迭代器,而对于嵌套循环i, j, k, l
  • @PaulPRO:“你确定吗?”没有。
【解决方案3】:

在 C 中,'\0'0 具有完全相同的值和类型。没有理由写'\0',除了丑化你的代码。但是,\0 在双引号内可能有助于生成嵌入空字节的字符串。

【讨论】:

  • 我不同意。它确实具有与0 相同的类型和值,但我更喜欢在将其用作字符时使用'\0'——就像我喜欢在指针上下文中使用NULL 而不是0 一样。
  • @Keith,我同意'\0',对于NULL,空指针的技术非常混乱,我更喜欢使用0,因为它是明确的。
  • @JensGustedt:NULL 有什么歧义?将其作为可变参数传递时需要对其进行强制转换,但同样适用于0
  • 使用NULL 可以隐藏你有指针类型而不是整数类型的问题,因为NULL 可以是整数类型。使用0 将使代码立即中断(或至少抛出相关警告),以便您可以修复它。我同意 Jens 的观点,也避免使用 NULL
  • @Keith,不幸的是 NULL 没有演员表可以在许多平台上运行,0 没有演员表会可靠地崩溃。
【解决方案4】:

ASCII 标准规定 NUL 字符编码为字节 0。除非您停止使用向后兼容 ASCII 的编码,否则不会出错。

【讨论】:

  • C 标准也规定了这一点。
  • 这个问题与ASCII无关,C标准甚至不需要使用。
  • @Artefacto,因此“除非您停止使用向后兼容 ASCII 的编码”。我没有尝试将 C 与 ASCII 链接。
  • @Artefacto:嗯,这个问题确实假设了 ASCII 特定的假设,即空白字符的值
  • @zneak:您是否使用与 ASCII 兼容的编码并不重要。任何 C 实现使用的 所有 编码,无论是否为 ASCII,都必须将空字符表示为 0。(碰巧,ASCII 和 EBCDIC 都这样做;如果不是这种情况,则 C 标准可能不需要它。)
猜你喜欢
  • 2019-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 2017-10-15
  • 2012-02-29
  • 2013-11-05
  • 1970-01-01
相关资源
最近更新 更多