Skip to content

第七部分:自定义数据类型


一、结构体的概念与定义

在前面的学习中,变量大多都是互相独立的,即使是内存中的地址也是互相毫无干系的。即使是数组,也只是要求其中的元素必须是同样的类型。那么可以不可以有一种结构,可以将一些不同类型的变量放在一起,而他们又具有一定的联系呢?例如一个学生的资料,其中有学号、姓名、性别、年龄、地址。C 语言中允许用户自己建立由不同类型数据组成的组合型数据结构,叫做“结构体”。可以理解为结构体也是一种数据类型,例如下面是一个自行创建的结构体类型:

c
struct Student
{
    int num;
    char name[20];
    char sex;
    int age;
    char add[30];
};

struct 是结构体类型的标识符,Student 是用户自定义的结构体名称,就像 int a 中的 a 是变量名称一样。这个结构体中有 5 个成员,分别是 numnamesexageadd,它们各自有自己的数据类型。这个结构体在内存中占 4 + 20 + 1 + 4 + 30 = 59 字节。上面定义的结构体可以这样示意:

Student
numnamesexageadd

定义结构体的一般形式为:

struct 结构体名
{
    //成员表列
    类型名 成员名;
};

定义结构体的时候不要忘了末尾有分号。结构体表现的是“包含”关系,如上例即表示 Student 中包含了 numnamesexageadd 五个元素。当然,结构体的成员可以属于另外一个结构体,例如:

c
struct Date
{
    int month;
    int day;
    int year;
} ;
struct Student
{
    char name[20];
    int age;
    char sex;
    char add[30];
    struct Date birthday;
} ;

这个时候,此结构体的结构如下图所示:

Student
nameagesexaddbirthday
monthdayyear

二、结构体类型的变量

当定义好了一个结构体,可以视为定义好了一个类型。比如学生是一个类型,这个类型具有学号姓名等属性。当我们定义好了这一类型的属性后,就要说明谁属于这个类型。比如王小明和张小红都是学生,这样它们就都具有学生这一类型应有的特征。这时候王小明和张小红就是学生这个结构体类型的变量。写在程序中如下:

c
struct Student
{
    char name[20];
    int num;
    char add[30];
} hong, ming;

这个时候hong和ming的结构如下图所示:

namenumadd
hong
ming

声明结构体类型的变量有两种方法,其中一种是在定义结构体的时候直接声明结构体变量,一般形式如下:

struct 结构体名
{
    //成员表列
    类型名 成员名;
} 变量1, 变量2, ……, 变量n;

注意分号是在变量表列之后的。还有一种定义方式,就是在已经定义好结构体之后,直接使用结构体名当类型名来定义,如下:

c
struct Student ming;

声明结构体变量的同时也可以直接对其进行初始化,下面这个例子介绍了结构体变量初始化和引用的方法:

c
#include<stdio.h>
int main()
{
    struct Student
    {
        int num;
        char sex;
        char name[20];
        char add[30];
    } a = {1405010314, 'M', ming, "Beijing"};
    printf("number : %d\n", a.num);
    printf("name : %s\n", a.name);
    printf("sex : %c\n", a.sex);
    printf("address : %s\n", a.add);
    return 0;
}

程序的运行结果是:

sh
number : 1405010314
name : ming
sex : M
address : Beijing

三、结构体数组

结构体数组的概念很好理解,即一次性声明具有相同类型的结构体变量。例如:

c
struct Student
{
    int num;
    char name[20];
} stu[3] = {001 , "ming" , 002 , "hong" , 003 , "hua"} ;

当结构体数组成员很多的时候,可以不在声明的时候进行初始化。

四、结构体与指针的结合

如果声明结构体类型的指针变量,这样的话就可以让指针在结构体数组上移动。结构体中有一个叫做 NEXT 的指针类型元素,它指向结构体数组的下一个元素首地址,这样一串结构体就被串连在一起,形成“链表”。一串结构体的最后一个变量 NEXT 成员指向 NULL,即空指针,代表一个链表的结束。链表属于数据结构部分的内容,不在这里详细讲解,有兴趣可以查阅参考资料 1 的教材内容。

五、枚举类型 enum

当一个变量只有几种值可以选择,这种变量称为枚举类型。声明枚举类型的关键字是 enum,变量的值域只在列出的值之中。例如:

c
enum Week{ Sun, Mon, Tue, Wed, Thu, Fri, Sat };

这个时候我们定义了一个枚举类型 Week,我们就可以用这个类型来定义变量:

c
enum Week Sep_1st, Oct_2nd;

这个时候 Sep_1stOct_2nd 都是 Week 类型的变量了,它们的值只能是已定义的 Week 类型的值其中之一。声明枚举类型的一般形式为:

c
enum 枚举名 { 枚举元素列表 };

六、其他的自定义类型

除了结构体和枚举类型之外,我们还有共用体类型没有详细讲解,可以查看参考资料 1 的教材自行了解。

我们还可以使用 typedef 来指定新的类型名来代替已有类型名。例如:

c
typedef int Zheng;

即指定 Zheng 这个类型名来代替 int。这个方法同样适用于重新定义结构体类型等。

七、练习题

  1. 建立一个学生通讯录,可以用户自行输入数据,然后全体输出。

  2. 定义一个结构体变量,包含年、月、日三个元素。然后设计一个函数可以计算这天在这一年中是第几天。注意闰年的问题。

© thebestxt.cc
辽ICP备16009524号-8
本站所有文章版权所有,转载请注明出处