「数据结构」构造数据类型

文章介绍了C语言中的结构体、联合和枚举三种数据类型。结构体允许组合多种基本类型的数据,可以用于表示复杂的数据结构,同时讨论了内存对齐的影响。联合则在同一时间只能存储一种类型的数据,但可以是不同类型的成员之一。枚举用于定义一组命名的整数常量,方便代码的可读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文发布于Hibiki33’s Blog,转载请标明出处。

结构体

结构体的定义和变量的声明

intfloatchar 等是由C语言本身提供的数据类型,不能再进行分拆,我们称之为 基本数据类型 ;而结构体可以包含多个基本类型的数据(或指针),也可以包含其他的结构体(或结构体指针),我们将它称为 复杂数据类型构造数据类型

例如一个学生,我们可以构造以下结构体:

struct student {
    char *name;     // 姓名
    int number;     // 学号
    int age;        // 年龄
    char class;     // 班级      
    float score;    // 成绩
};

通过构造结构体,我们可以方便的对一个拥有一定属性的聚合进行操作(如筛选、条件排序等)。

既然该结构体已经成为一个数据类型,那么就可以用它来申明变量,如:

struct student stu1, stu2;

此外,在数据结构课程中,常用如下格式进行结构体的定义:

typedef struct student {
    char *name;    
    int number; 
    int age; 
    char class;    
    float score;  
} stu, *STU;

这种写法表示:将 struct student 这个语句定义为(或者说表示为)stu 这种简写,而 *s 表示这个结构体的指针。在声明变量时:

stu stu1, stu2;     // 这种写法与上述 struct student stu1, stu2; 等价
STU stu3;           // 表示声明了一个student结构体的指针stu3 当然此时stu3没有指向任何地址

此外,自引用结构将会在链表部分详细说明。

结构体的存储空间

理论上讲结构体的各个成员在内存中是连续存储的,和数组非常类似,例如上面的结构体变量 stu1stu2 的内存分布为4 + 4 + 4 + 1 + 4。但实际上,当我们运行以下程序段:

#include <stdio.h>

struct student {
    char *name;     
    int number;   
    int age;       
    char class;         
    float score;    
};

int main(int argc, char **args)
{
    struct student stu1, stu2;
    printf("%d\n", sizeof(stu1));
    return 0;
}

我们会发现输出了24,这与C语言的内存对齐有关,目的是提高寻址效率,读者可以自行查阅资料深入了解。

联合

联合的定义

联合是一种数据类型,该类型变量可以在不同时间内维持定义它的不同类型和不同长度的对象,也就是说提供单独的变量,以便合理地保存几种类型中的任何一类变量。

定义形式:

union 联合名 {分量表} 联合变量名;

例如:

union v_tag {
    int ival;
    float fval;
    char *pval;
} uval;

if(utype == INT)         printf("%d\n", uval.ival);
else if (utype == FLOAT) printf("%f\n", uval.fval);
else if(utype == STRING) printf("%s\n", uval.pval);
else                     printf("bad type\n");

注意:使用联合,用法必须一致,即取出的类型必须是最近存入的类型。因此,在使用联合时,要记住当前存于联合中的类型是什么,不允许存入是一种类型,而取出是另一种类型。

联合可以出现在结构和数组中,数组和结构也可以出现在联合中:

struct symtab {
    char *name;
    int flags;
    int utype;
    union {
        int ival;
        float fval;
        char *pval;
    } uval;
};

声明及使用:

struct symtab st[100];
printf("%d", st[10].uval.ival);

结构体和联合的异同

在定义或说明形式上,unionstruct 很类似,但在任何时刻联合只允许联合中说明的某一成员留在联合里。结构由多个成员(分量)所组成,而联合只有一个成员,只不过该成员的名字和类型可以在规定的几个里选定一个。

因此,联合可以看作是一个特殊的结构,其所有成员在结构中的位移量都是0,当对联合变量分配存贮空间时,应保证它能容纳最大的一个成员的大小,而存贮空间的边界应能适于联合中的所有可选成员的类型。

请添加图片描述

对联合成员的引用方式完全和结构的情况一样。

枚举

枚举的语法定义格式为:

enum 枚举名 {枚举元素1, 枚举元素2};

比如对于一星期7天,我们往常会这样定义:

#define MON  0
#define TUE  1
#define WED  2
#define THU  3
#define FRI  4
#define SAT  5
#define SUN  6

如果使用枚举的话:

enum DAY {
      MON, TUE, WED, THU, FRI, SAT, SUN		// 第一个枚举成员的默认值为整型的0 后续枚举成员在前一个基础上加1
};

可以在定义枚举类型时改变枚举元素的值:

enum season {spring, summer=3, autumn, winter};

没有指定值的枚举元素,其值为前一元素加 1。也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5。

定义和声明与结构体都很类似。例如:

#include <stdio.h>
#include <stdlib.h>
int main()
{
 
    enum color { red=1, green, blue };
    enum color favorite_color;
 
    printf("请输入你喜欢的颜色: (1. red, 2. green, 3. blue): ");
    scanf("%u", &favorite_color);
 
    switch (favorite_color)
    {
    case red:
        printf("你喜欢的颜色是红色");
        break;
    case green:
        printf("你喜欢的颜色是绿色");
        break;
    case blue:
        printf("你喜欢的颜色是蓝色");
        break;
    default:
        printf("你没有选择你喜欢的颜色");
    }
    
    return 0;
}

当输入1时,输出为:

请输入你喜欢的颜色: (1. red, 2. green, 3. blue): 1
你喜欢的颜色是红色

此外,对于上述例子,我们可以对原本的整型变量进行类型转换:

int a = 1;
favorite_color = (enum color) a;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值