结构体

引子

设计程序时,最重要的步骤之一就是选择表示数据的方法。在许多情况下,简单变量甚至是数组还不够。为此,C提供了结构变量(structure variable)提高表示数据的能力,它能够创造新的形式。

建立结构体声明

小栗子

需求:需要打印一份图书目录。里面包含每本书的各种信息:书名、作者、出版社、版权日期和价格。其中一些元素(例如书名和作者)可以储存在字符数组中,其他项目需要一个int或者float。如果使用5哥不同的数组分别记录每一项都比较繁琐,尤其是要创建多份列表:一份按书名排序、一份按作者排序、一份按照价格排序等。如果能把图书目录的信息都包含在一个数组里更好,其中每个元素包含一本书的相关信息。

因此,就需要一种既能包含字符串也能包含数字的数据形式,而且还要保持各信息的独立。结构体就满足这种情况下的需求。

struct Book { /* 结构体模板:标记为Book (我们通常使用首字母大写的方式来标识结构体) */
    char title[128]; // 成员 or 字段
    char author[40];
    char publisher[256];
    int date;
    float price;
}
​
int main (void) {
    struct Book book; /* 把book声明为一个Book类型的变量 */
    printf("请输入书名:");
    scanf("%s", book.title);
    printf("请输入作者:");
    scanf("%s", book.author);
    printf("请输入出版社:");
    scanf("%s", book.publisher);
    printf("请输入出版日期:");
    scanf("%d", book.date);
    printf("请输入价格:");
    scanf("%f", book.price);
    
    return 0;
}
​
// Output
请输入书名:《C Primer Plus》
请输入作者:Stephen Prata
请输入出版社:人民邮电出版社
请输入出版日期:201604
请输入价格:59.4

建立结构声明

结构声明(structure declaration)描述了一个结构的组织布局。声明类似下面这样:

struct Book {
    char title[128];
    char author[40];
    float price;
}

该声明描述了一个由两个字符数组和一个float类型变量组成的结构。该声明并未创建实际的数据对象,只描述了该对象由什么组成。

分析下,首先是关键字struct,它表明跟在其后的是一个结构,后面是一个标记 (例子为Book),我们可以使用该标记引用该结构。所以,我们可以在后面的程序中这样声明:

struct Book book1;

这把book1声明为一个使用Book结构布局的结构变量。

在结构声明中,用一对花括号括起来的是结构成员列表。每个成员都用自己的声明来描述。例如,title部分就是一个内涵128个元素的char类型的数组。成员可以是任意一种C的数据类型,甚至可以是其他结构体。右花括号后面的分号是声明所必需的,表示结构布局定义结束。可以把这个声明放在所有函数的外部,也可以放在一个函数定义的内部。如果把结构声明置于一个函数的内部,它的标记就只限于该函数内部使用。如果置于外部,那么该声明之后的所有函数都能使用标记。

定义结构变量

结构有两层含义。一层含义是“结构布局”,结构布局告诉编译器如何表示数据,但是它并未让编译器为数据分配空间。下一步是创建一个结构变量,即是结构的另一层含义。

struct Book book1; // 创建结构变量

初始化结构体

初始化变量和数组如下:

int count = 0;

int array[7] = {0, 1, 2, 3, 4, 5, 6};

结构变量也可以像这样进行初始化,初始化一个结构变量与初始化数组的语法类似:

struct Book book1 = {
    "C Primer Plus",
    "Stephen Prata",
    59.4
};

我们使用在一对花括号中括起来的初始化列表进行初始化,各初始化项用逗号分隔。因此,title成员可以被初始化为一个字符串,price可以被初始化为一个数字。为了让初始化项与结构中各成员的关联更加明显,我们让每个成员的初始化项都独占一样。这样做只是为了提高代码的可读性,对编译器而言,只需要用逗号分隔各成员的初始化项即可。

访问结构体成员

结构类似于一个“超级数组”,这个超级数组中,可以是一个元素为char类型,下一个元素为float类型,下一个元素为int数组。可以通过数组下标单独访问数组中的个元素,那么,如何访问结构中的成员?使用结构成员运算符 点 (.) 访问结构中的成员。例如,book1.price即访问book1的price元素。可以像使用任何float类型变量那样使用book1.price。与此类似,可以像使用字符数组那样使用 book1.title。

本质上,.title、.author和.price的作用相当于是Book结构的下标。

所以在初始化结构体变量时,也可以指定成员:

struct Book book1 = {.price = 59.4};

既然已经是指定成员赋值了,那么就不用再考虑顺序:

struct Book book1 = {
    .price = 59.4,
    .title = "C Primer Plus",
    .author = "Stephen Prata"
}
# C  结构体 
樱花正含苞待放,春天就要来了🌸
标题:结构体
作者:bogendihong
地址:https://myjinji.top/articles/2020/11/15/1605404898205.html

评论

取消