非常教程

C参考手册

C 语法

Array initialization

当初始化一个数组类型的对象时,初始化器必须是一个字符串文字(可选地用大括号括起来)或者是一个由数组成员初始化的大括号括起来的列表:

= string_literal

(1)

= { expression , ... } = { designator(optional) expression , ... }

(2)

(until C99)(since C99)

1)用于字符和宽字符数组的字符串字面初始值设定项

2)用逗号分隔的数组元素的初始值表达式列表,可选地使用形式为[constant-expression 的数组指示符] = (自 C99开始)

已知大小的阵列和未知大小的阵列可能被初始化,但不是 VLA。(自 C99以来)。

所有未明确初始化的数组元素都是以与具有静态存储持续时间的对象相同的方式隐式初始化的。

从字符串初始化

字符串文字(可以用大括号括起来)可以用作匹配类型数组的初始值设定项:

  • 普通字符串文字和 UTF-8字符串(因为 C11)可以初始化任何字符类型的阵列(charsigned charunsigned char
  • 带前缀的宽字符串文字可用于初始化任何兼容的类型的数组(忽略 cv 资格) wchar_t

u-prefixed wide string literals can be used to initialize arrays of any type compatible with (ignoring cv-qualifications) char16_t U-prefixed wide string literals can be used to initialize arrays of any type compatible with (ignoring cv-qualifications char32_t

(since C11)

  • 带 u 前缀的宽字符串文字可用于初始化任何兼容类型的数组(忽略 cv 资格) char16_t
  • 带U前缀的宽字符串文字可以用来初始化任何兼容类型的数组(忽略 cv 资格) char32_t

(since C11)

字符串文字的连续字节或宽字符串文字的宽字符(包括终止空字节/字符)初始化数组的元素:

char str[] = "abc"; // str has type char[4] and holds 'a', 'b'. 'c', '\0'
wchar_t wstr[4] = L"猫"; // str has type wchar_t[4] and holds L'猫', '\0', '\0', '\0'

如果数组的大小已知,则它可能比字符串文字的大小小1,在这种情况下,将终止空字符被忽略:

char str[3] = "abc"; // str has type char[3] and holds 'a', 'b', 'c'

请注意,与使用直接访问字符串字面值不同,此数组的内容是可修改的char* str = "abc";

从大括号列表中初始化

当一个数组用初始化器的大括号初始化时,列表中的第一个初始化器初始化索引为0的数组元素(除非指定了指定符号)(自C99开始),并且每个后续的初始化器都没有指定符(自C99开始)初始化索引1处的数组元素大于前一个初始化器初始化的数组元素。

int x[] = {1,2,3}; // x has type int[3] and holds 1,2,3
int y[5] = {1,2,3}; // y has type int[5] and holds 1,2,3,0,0
int z[3] = {0}; // z has type int[3] and holds all zeroes

在初始化已知大小的数组时,提供比元素更多的初始化程序是错误的(除了从字符串文字初始化字符数组时)。

A designator causes the following initializer to initialize of the array element described by the designator. Initialization then continues forward in order, beginning with the next element after the one described by the designator. int n5 = {4=5,0=1,2,3,4} // holds 1,2,3,4,5 int aMAX = { // starts initializing a0 = 1, a1 = 3, ... 1, 3, 5, 7, 9, MAX-5 = 8, 6, 4, 2, 0 } // for MAX=6, array holds 1,8,6,4,2,0 // for MAX=13, array holds 1,3,5,7,9,0,0,0,8,6,4,2,0 ("sparse array")

(since C99)

初始化未知大小的数组时,指定初始化程序的最大下标确定正在声明的数组的大小。

嵌套数组

如果数组的元素是数组,结构体或联合体,则大括号括起来的初始化程序中相应的初始化程序是对这些成员有效的任何初始化程序,除了它们的大括号可以省略如下:

如果嵌套的初始化程序以开始大括号开始,则整个嵌套初始化程序直到其大括号初始化相应的数组元素:

int y[4][3] = { // array of 4 arrays of 3 ints each (4x3 matrix)
    { 1 },      // row 0 initialized to {1, 0, 0}
    { 0, 1 },   // row 1 initialized to {0, 1, 0}
    { [2]=1 },  // row 2 initialized to {0, 0, 1}
};              // row 3 initialized to {0, 0, 0}

如果嵌套的初始化程序不是以大括号开头的话,那么只有列表中的足够的初始化程序可以用来解释子数组 struct struct 或 union 的元素或成员; 任何剩余的初始化器都将被初始化为下一个数组元素:

int y[4][3] = {    // array of 4 arrays of 3 ints each (4x2 matrix)
1, 3, 5, 2, 4, 6, 3, 5, 7 // row 0 initialized to {1, 3, 5}
};                        // row 1 initialized to {2, 4, 6}
                          // row 2 initialized to {3, 5, 7}
                          // row 3 initialized to {0, 0, 0}
 
struct { int a[3], b; } w[] = { { 1 }, 2 }; // array of structs
   // { 1 } is taken to be a fully-braced initializer for element #0 of the array
   // that element is initialized to { {1, 0, 0}, 0}
   // 2 is taken to be the first initialized for element #1 of the array
   // that element is initialized { {2, 0, 0}, 0}

Array designators may be nested; the bracketed constant expression for nested arrays follows the bracketed constant expression for the outer array: int y4 = {0=1, 1=1, 2=1}; // row 0 initialized to {1, 0, 0} // row 1 initialized to {0, 1, 0} // row 2 initialized to {1, 0, 0} // row 3 initialized to {0, 0, 0}

(since C99)

笔记

数组初始值设定项中子表达式的求值顺序在 C 中是不确定的(但在c ++ 11以后,不在 C ++中):

int n = 1;
int a[2] = {n++, n++}; // unspecified, but well-defined behavior,
                       // n is incremented twice (in arbitrary order)
                       // a initialized to {1, 2} and to {2, 1} are both valid
puts((char[4]){'0'+n} + n++); // undefined behavior:
                              // increment and read from n are unsequenced

在 C 中,初始化程序的支撑列表不能为空。C ++允许空列表:

int a[3] = {0}; // valid C and C++ way to zero-out a block-scope array
int a[3] = {}; // invalid C but valid C++ way to zero-out a block-scope array

与所有其他初始化一样,初始化器列表中的每个表达式在初始化静态或线程本地存储持续时间数组时都必须是常量表达式:

static char* p[2] = {malloc(1), malloc(2)}; // error

int main(void)
{
    // The following four array declarations are the same
    short q1[4][3][2] = {
        { 1 },
        { 2, 3 },
        { 4, 5, 6 }
    };
 
    short q2[4][3][2] = {1, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 4, 5, 6};
 
    short q3[4][3][2] = {
        {
            { 1 },
        },
        {
            { 2, 3 },
        },
        {
            { 4, 5 },
            { 6 },
        }
    };
 
    short q4[4][3][2] = {1, [1]=2, 3, [2]=4, 5, 6};
 
 
    // Character names can be associated with enumeration constants
    // using arrays with designators:
    enum { RED, GREEN, BLUE };
    const char *nm[] = {
        [RED] = "red",
        [GREEN] = "green",
        [BLUE] = "blue",
    };
}

参考

  • C11标准(ISO / IEC 9899:2011):
    • 6.7.9 / 12-38初始化(p:140-144)
  • C99标准(ISO / IEC 9899:1999):
    • 6.7.8 / 12-38初始化(p:126-130)
  • C89 / C90标准(ISO / IEC 9899:1990):
    • 3.5.7 / 12-初始化

C 语法相关

1.#define directive
2.#elif directive
3.#else directive
4.#endif directive
5.#error directive
6.#if directive
7.#ifdef directive
8.#ifndef directive
9.#include directive
10.#line directive
11.#pragma directive
12.alignas
13.Alternative operators and tokens
14.Analyzability
15.Arithmetic operators
16.Arithmetic types
17.Array declaration
18.ASCII Chart
19.Assignment operators
20. types
21.Basic concepts
22.Bit fields
23.break statement
24.C language
25.C Operator Precedence
26.cast operator
27.character constant
28.Comments
29.Comparison operators
30.compound literals
31.Conditional inclusion
32.Conformance
33.const type qualifier
34.Constant expressions
35.continue statement
36.Declarations
37.do-while loop
38.Enumerations
39.Escape sequences
40.Expressions
41.External and tentative definitions
42.File scope
43.floating constant
44.for loop
45.Function declarations
46.Function definitions
47.Functions
48.Generic selection
49.goto statement
50.Identifier
51.if statement
52.Implicit conversions
53.Increment/decrement operators
54.Initialization
55.inline function specifier
56.integer constant
57.Lifetime
58.Logical operators
59.Lookup and name spaces
60.Main function
61.Member access operators
62.Memory model
63.Objects and alignment
64.Order of evaluation
65.Other operators
66.Phases of translation
67.Pointer declaration
68.Preprocessor
69.restrict type qualifier
70.return statement
71.Scalar initialization
72.Scope
73.sizeof operator
74.Statements
75.static assert declaration
76.Static storage duration
77.Storage-class specifiers
78.string literals
79.Struct and union initialization
80.Struct declaration
81.switch statement
82.Thread storage duration
83.Type
84.Type
85.Typedef declaration
86.Undefined behavior
87.Union declaration
88.Value categories
89.Variadic arguments
90.volatile type qualifier
91.while loop
92._Alignof operator
93._Noreturn function specifier
C

C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。