C语言中的指定初始化器是什么?

37
我有一个作业需要理解C语言中的“指定初始化器”是什么,以及使用它来初始化变量意味着什么。我对这个术语不熟悉,也找不到确切的定义。请问,“指定初始化器”在C语言中是什么?

评论已被移至聊天室,请勿在此处继续讨论。在此评论之前,请查看评论的目的。通常不请求澄清或建议改进的评论应作为答案、[元数据]或[聊天室]中的一部分。继续讨论的评论可能会被删除。 - Jean-François Fabre
3个回答

46

指定初始化器有两种类型:

1)它提供了一种快速初始化数组中特定元素的方法:

int foo[10] = { [3] = 1, [5] = 2 };

除了索引为3的元素将被设置为1,索引为5的元素将被设置为2之外,它将所有元素foo都设置为0。

2)它提供了一种显式初始化struct成员的方法。例如,用于

struct Foo { int a, b; };

你可以编写代码

struct Foo foo { .a = 1, .b = 2 };

请注意,在这种情况下,没有显式初始化的成员将被初始化,就好像该实例具有静态持续时间。


这两种方式都是标准C,但请注意,C ++不支持它们(因为在那种语言中构造函数可以完成此工作)。


请查看此链接以了解有关C ++的更多信息。我相信它已经为下一个标准做好了准备。 - DeiDei
@AnttiHaapala:需要在制定规则的行之前挖出我的标准,以便进行最后的评论。(唉,我现在正在乘坐火车)。我认为这是正确的。 - Bathsheba
至少未命名的结构成员未初始化。http://port70.net/~nsz/c/c11/n1570.html#6.7.9p9 - Antti Haapala -- Слава Україні
变量的成员(未在代码中显式初始化的)将由编译器自动初始化为0。就像所有静态和全局变量在代码中未显式初始化时总是自动初始化为0一样。 - abetancort

20
指定初始化器自ISO C99以来出现,它是在C中初始化struct、union或array时一种不同且更动态的方式。
与标准初始化的最大区别在于,您不必按固定顺序声明元素,还可以省略元素。
来自GNU指南
标准C90要求初始化器的元素按照固定顺序出现,与初始化的数组或结构的元素顺序相同。
在ISO C99中,您可以以任意顺序给出元素,指定它们适用于的数组索引或结构字段名称,GNU C也允许在C90模式下作为扩展使用。

示例

1. 数组索引

标准初始化

  int a[6] = { 0, 0, 15, 0, 29, 0 };

指定初始化
  int a[6] = {[4] = 29, [2] = 15 }; // or
  int a[6] = {[4]29 , [2]15 }; // or
  int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

2. 结构体或联合体:

标准初始化

struct point { int x, y; };

指定初始化
 struct point p = { .y = 2, .x = 3 }; or
 struct point p = { y: 2, x: 3 };

3. 将命名元素与普通的C初始化连续元素相结合:
标准初始化
int a[6] = { 0, v1, v2, 0, v4, 0 };

指定初始化
int a[6] = { [1] = v1, v2, [4] = v4 };

4. 其他:

给数组初始化器的元素加上标签

int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
                        ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };

在等号之前,写一系列的‘.fieldname’和‘[index]’指示符来指定一个嵌套的子对象进行初始化。
struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };

指南


0

C99标准草案

这并不是特别有启发性的,只是为了满足我自己的好奇心:WG14/N1256 C99标准草案

6.7.8 Initialization

designator-list:
  designator
  designator-list designator

designator:
  [ constant-expression ]
  . identifier

Constraints

6 If a designator has the form

[ constant-expression ]

then the current object (defined below) shall have array type and the expression shall be an integer constant expression. If the array is of unknown size, any nonnegative value is valid.

7 If a designator has the form

. identifier

then the current object (defined below) shall have structure or union type and the identifier shall be the name of a member of that type.

Semantics

17 Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.129) In contrast, a designation causes the following initializer to begin initialization of the subobject described by the designator. Initialization then continues forward in order, beginning with the next subobject after that described by the designator

18 Each designator list begins its description with the current object associated with the closest surrounding brace pair. Each item in the designator list (in order) specifies a particular member of its current object and changes the current object for the next designator (if any) to be that member.131) The current object that results at the end of the designator list is the subobject to be initialized by the following initializer.

EXAMPLE 9 Arrays can be initialized to correspond to the elements of an enumeration by using designators:

enum { member_one, member_two };
const char *nm[] = {
    [member_two] = "member two",
    [member_one] = "member one",
}

EXAMPLE 11 Designators can be used to provide explicit initialization when unadorned initializer lists might be misunderstood:

struct { int a[3], b; } w[] =
    { [0].a = {1}, [1].a[0] = 2 };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接