使用八进制常量初始化 char 数组

char array initialization with octal constant

我看到一条评论说用 "[=12=]1" 初始化 char 数组会将 nul 作为第一个字符。我已经看到 [=13=] 在哪里设置了 nul。

未经编辑的评论:

char input[SIZE] = ""; is sufficient initialization. while ( '[=18=]1' == input[0]) doesn't do what you think it is doing if you have initialized input[SIZE] = "[=18=]1"; (which creates an empty-string with the nul-character as the 1st character.)

这个节目

#include <stdio.h>
#define SIZE 8
int main ( void) {
    char input[SIZE] = "[=10=]1";

    if ( '[=10=]1' == input[0]) {//also tried 1 == input[0]
        printf ( "octal 1\n\n");
    }
    else {
        printf ( "empty string\n");
    }
    return 0;
}

运行 在 Linux 上,用 gcc 编译,输出:

octal 1

所以第一个字符是 1 而不是 '[=16=]'
这是标准行为还是只是 Linux 和 gcc 的行为?为什么不设置 nul?

I saw a comment that said initialization of a char array with "[=13=]1" would put a nul as the first character.

该评论有误。

来自 6.4.4.1 整数常量,第 3 段,强调我的:

An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only.

但是我们在这里看到的根本不是整数常量。实际上,我们这里有一个 八进制转义序列 。定义如下(在6.4.4.4字符常量中):

octal-escape-sequence:
        \ octal-digit
        \ octal-digit octal-digit
        \ octal-digit octal-digit octal-digit

整数常量和字符常量的定义是 "greedy",如第 7 段所述:

Each octal or hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence.

这意味着,如果第一个八进制数字后跟可能是八进制数字的内容,则下一个字符被认为是属于该常量的八进制数字(对于字符常量,最多为三个——对于整数常量则不然!)。

因此,您的 "[=11=]1" 确实是一个值为 1 的字符。

请注意,虽然 octal 字符常量 运行 最多三个字符(如果根据需要用前导零填充这样的常量使用起来非常安全三位数的长度),十六进制 字符常量 运行 只要有十六进制数字(可能会溢出它们要初始化的 char 类型)。

http://c0x.coding-guidelines.com/6.4.4.4.html

八进制序列定义为:

  octal-escape-sequence:
            \ octal-digit
            \ octal-digit octal-digit
            \ octal-digit octal-digit octal-digit

和项目 873:

The octal digits that follow the backslash in an octal escape sequence are taken to be part of the construction of a single character for an integer character constant or of a single wide character for a wide character constant.

还有项目 877:

Each octal or hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence.

因此行为是正确的。 "\001" 位置 0 不应有空字节。

Is this the standard behavior or just something with Linux and gcc? Why does it not set a nul?

您提供的代码的行为符合标准要求。在字符串文字和整型字符常量中,八进制转义都可能包含一位、两位或三位数字,C 标准规定

Each octal [...] escape sequence is the longest sequence of characters that can constitute the escape sequence.

(C2011, 6.4.4.4/7)

在这种情况下,[=12=] 是八进制转义序列,而不是空字符的特殊独立代码。上述引文的更广泛的上下文将清楚地表明这一点。

在字符串字面值"[=13=]1"中,反斜杠后面跟着三个八进制数字,八进制转义可以有三个数字,因此转义序列由反斜杠和所有三个数字组成。结果字符串的第一个字符是整数值 1 的字符。

如果出于某种原因你想要一个由空字符后跟十进制数字 0 和 1 组成的字符串文字,那么你可以用完整的三位转义符来表示空值,

"[=10=]001"

或者像这样拆分:

"[=11=]" "01"

C 将连接相邻的字符串文字以产生所需的结果。