非常教程

C参考手册

C 语法

Struct declaration

结构是一种由一系列成员组成的类型,其存储按有序顺序进行分配(与union相反,这是一种由存储重叠的成员序列组成的类型)。

union除了使用的关键字之外,结构的类型说明符与 类型说明符相同:

句法

结构名称(可选){结构声明列表}

(1)

结构名称

(2)

1)结构定义:引入新的类型结构名称并定义它的含义

2)如果在struct名称上使用它自己的行;,则声明但不定义该结构name(请参见下面的前向声明)。在其他上下文中,命名先前声明的结构。

name

-

正在定义的结构的名称

结构声明列表

-

任何数量的变量声明,位域声明和静态断言声明。不完整类型的成员和函数类型的成员是不允许的(除了下面描述的灵活数组成员)

说明

在一个结构对象中,其元素的地址(以及位字段分配单元的地址)按照成员定义的顺序增加。指向结构的指针可以转换为指向其第一个成员的指针(或者,如果该成员是位域,则指向其分配单元)。同样,可以将指向结构第一个成员的指针转换为指向封闭结构的指针。在结构的任何两个成员之间或者在最后一个成员之后,可能存在未命名的填充,但不在第一个成员之前。结构的大小至少与其成员大小的总和一样大。

如果一个结构至少定义了一个指定的成员,那么它允许额外地声明它的最后一个成员为不完整的数组类型。当访问灵活数组成员的元素时(在使用运算符的表达式中,或者使用灵活数组成员的名称作为右手边操作数),那么结构的行为就好像数组成员具有最长的大小适合为该对象分配的内存。如果没有分配额外的存储空间,则它的行为就像一个具有1个元素的数组,除非该行为是未定义的(如果访问该元素或产生了经过该元素的指针)。初始化,sizeof和赋值运算符忽略了灵活的数组成员。具有灵活数组成员的结构(或其最后一个成员是具有灵活数组成员的结构的联合结构)不能以数组元素或其他结构成员的形式出现。struct s {int n; double d []; }; // sd是一个灵活的数组成员struct s t1 = {0}; // OK,d就好像是double d1,但UB访问struct s t2 = {1,{4.2}}; //错误:初始化忽略灵活数组//如果sizeof(double)== 8 struct s * s1 = malloc(sizeof(struct s)+ 64); //好像d是双d8 struct s * s2 = malloc(sizeof(struct s)+ 46); //好像d是double d5 s1 = malloc(sizeof(struct s)+ 10); //现在好像d是double d1 s2 = malloc(sizeof(struct s)+ 6); //相同,但UB访问double * dp =&(s1-> d0); // OK * dp = 42; // OK dp =&(s2-> d0); // OK * dp = 42; //未定义行为* s1 = * s2; //只复制sn,而不是sd的任何元素//除了在sizeof(struct s)中捕获的元素外,

(自C99以来)

类似于联合,一个结构的未命名成员的类型是一个没有名字的结构被称为匿名结构。匿名结构的每个成员都被认为是封闭结构或联合的成员。如果封闭的结构或联合也是匿名的,则这将递归应用。struct v {union {//匿名联合结构{int i,j; }; //匿名结构struct {long k,l; } w; }; int m; } v1; v1.i = 2; //有效v1.k = 3; //无效:内部结构不是匿名的v1.wk = 5; // valid与union类似,如果struct没有任何指定成员(包括通过匿名嵌套结构或联合获得的成员)定义,则程序的行为是未定义的。

(自C11以来)

前向声明

以下表格的声明。

结构名称;

隐藏标签名称空间中名称名称的任何先前声明的含义,并将名称声明为当前作用域中的新结构名称,稍后将对其进行定义。在定义出现之前,此结构名称的类型不完整。

这允许相互引用的结构:

struct y;
struct x { struct y *p; /* ... */ };
struct y { struct x *q; /* ... */ };

请注意,只需在另一个声明中使用结构标签即可引入新的结构名称,但如果在标签名称空间中存在以前声明的具有相同名称的结构,则该标签将引用该名称。

struct s* p = NULL; // tag naming an unknown struct declares it
struct s { int a; }; // definition for the struct pointed to by p
void g(void)
{
    struct s; // forward declaration of a new, local struct s
              // this hides global struct s until the end of this block
    struct s *p;  // pointer to local struct s
                  // without the forward declaration above,
                  // this would point at the file-scope s
    struct s { char* p; }; // definitions of the local struct s
}

关键词

struct.

注释

有关结构初始化程序的规则,请参阅结构初始化。

因为不完整类型的成员是不允许的,并且结构类型直到定义结束才会完成,所以结构体不能拥有自己类型的成员。允许指向它自己的类型的指针,并且通常用于实现链接列表或树中的节点。

因为结构声明不会建立范围,所以struct-declaration-list中的声明引入的嵌套类型,枚举和枚举器在定义了结构的周围范围内是可见的。

#include <stddef.h>
#include <stdio.h>
 
int main(void)
{
    struct car { char *make; char *model; int year; }; // declares the struct type
    // declares and initializes an object of a previously-declared struct type
    struct car c = {.year=1923, .make="Nash", .model="48 Sports Touring Car"};
    printf("car: %d %s %s\n", c.year, c.make, c.model);
 
    // declares a struct type, an object of that type, and a pointer to it
    struct spaceship { char *make; char *model; char *year; }
        ship = {"Incom Corporation", "T-65 X-wing starfighter", "128 ABY"},
        *pship = &ship;
    printf("spaceship: %s %s %s\n", ship.year, ship.make, ship.model);
 
    // addresses increase in order of definition
    // padding may be inserted
    struct A { char a; double b; char c;};
    printf("offset of char a = %zu\noffset of double b = %zu\noffset of char c = %zu\n"
           "sizeof(struct A)=%zu\n", offsetof(struct A, a), offsetof(struct A, b),
           offsetof(struct A, c), sizeof(struct A));
    struct B { char a; char b; double c;};
    printf("offset of char a = %zu\noffset of char b = %zu\noffset of double c = %zu\n"
           "sizeof(struct B)=%zu\n", offsetof(struct B, a), offsetof(struct B, b),
           offsetof(struct B, c), sizeof(struct B));
 
    // A pointer to a struct can be cast to a pointer to its first member and vice versa
    char* pmake = (char*)&ship;
    pship = (struct spaceship *)pmake;
}

可能的输出:

car: 1923 Nash 48 Sports Touring Car
spaceship: 128 ABY Incom Corporation T-65 X-wing starfighter
offset of char a = 0
offset of double b = 8
offset of char c = 16
sizeof(struct A)=24
offset of char a = 0
offset of char b = 1
offset of double c = 8
sizeof(struct B)=16

参考

  • C11标准(ISO / IEC 9899:2011):
    • 6.7.2.1结构和联合说明符(p:112-117)
  • C99标准(ISO / IEC 9899:1999):
    • 6.7.2.1结构和联合说明符(p:101-104)
  • C89 / C90标准(ISO / IEC 9899:1990):
    • 3.5.2.1结构和联合说明符

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.Array initialization
19.ASCII Chart
20.Assignment operators
21. types
22.Basic concepts
23.Bit fields
24.break statement
25.C language
26.C Operator Precedence
27.cast operator
28.character constant
29.Comments
30.Comparison operators
31.compound literals
32.Conditional inclusion
33.Conformance
34.const type qualifier
35.Constant expressions
36.continue statement
37.Declarations
38.do-while loop
39.Enumerations
40.Escape sequences
41.Expressions
42.External and tentative definitions
43.File scope
44.floating constant
45.for loop
46.Function declarations
47.Function definitions
48.Functions
49.Generic selection
50.goto statement
51.Identifier
52.if statement
53.Implicit conversions
54.Increment/decrement operators
55.Initialization
56.inline function specifier
57.integer constant
58.Lifetime
59.Logical operators
60.Lookup and name spaces
61.Main function
62.Member access operators
63.Memory model
64.Objects and alignment
65.Order of evaluation
66.Other operators
67.Phases of translation
68.Pointer declaration
69.Preprocessor
70.restrict type qualifier
71.return statement
72.Scalar initialization
73.Scope
74.sizeof operator
75.Statements
76.static assert declaration
77.Static storage duration
78.Storage-class specifiers
79.string literals
80.Struct and union initialization
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 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。