结构体,联合体,枚举类型

一.结构体

一.结构体变量定义,初始化,结构体内容的访问

首先,结构体变量的定义,需要首先搭建结构体的框架,然后定义变量,其次,对其初始化类似于数组的初始化,即初始化每一个字段的内容。

#include <stdio.h>
struct person{
    char name[20];
    int age;
    char gender;
    float height;
} hug2 = {"xiaohong", 18, 'F', 1.62};
void output(struct person *p){
    printf("%s %d %c %f\n", p->name, p->age, p->gender, p->height);
    return ;
}
int main() {
    struct person hug = {"xiaoming", 18, 'M', 1.72};
    printf("%s %d %c %f\n", hug.name, hug.age, hug.gender, hug.height);
    output(&hug); 
    output(&hug2);
    return 0; 
}

上述代码中,对于结构体的访问,可以通过变量名,即hug.name一类的方式直接访问,也可以利用指针进行间接访问。

还要注意的是,除了像hug这样定义结构体变量之外,还可以通过在结构体后直接加变量名来定义,如hug2。

在第一种定义方式中,hug的类型名struct person太长,我们可以用typedef关键字来对其重命名。

#include <stdio.h>
 typedef struct person{
    char name[20];
    int age;
    char gender;
    float height;
} person;
void output(struct person *p){
    printf("%s %d %c %f\n", p->name, p->age, p->gender, p->height);
    return ;
}
int main() {
    person hug = {"xiaoming", 18, 'M', 1.72};
    output(&hug); 
    return 0; 
}

二.结构体占用内存大小

想要解决这个问题,就必须知道结构体的对齐规则。

1.类型都有对齐值,内建类型的对齐值就是其自身的大小

2.结构体的对齐值等于其成员中的最大对齐值

3.成员被存储在其整数倍的对齐值位置上

4.可以通过#pragma pack 限制对齐值的最大值

所以,像上面的结构体struct person来说,name对齐值为1,age对齐值为4,gender对齐值为1,height对齐值为4,则该结构体对齐值为4。

另外,结构体在申请内存空间时,是按其对齐值大小申请的,对于struct person来说,他先申请四个字节的空间,申请五次,存放name,然后再申请一次存放age,再申请一次存放gender,但是在这多余的三个字节中,根据第三条,无法存height,因为其对齐值为4,所以在申请一次存height,一共申请八次,即32字节,所以该结构体大小为32字节。

注意,内存空间是从0开始标记的,如第1个字节为0,第32个字节为31.

当利用#pragma pack时,结构体内成员的对齐值也会受到其限制,即,大于给定最大对齐值的成员起对齐值变为该最大对齐值,如#pragma pack(4),则对于double类型的变量其对齐值变为4

二.联合体

联合体通俗的说就是在同一片内存空间下存储不同的数据类型,他的定义与初始化与结构体相似,就不赘述,其关键字为union。

当改变联合体内部成员的数据是,其他成员在对应位置的数据也会因此改变,联合体的大小取决于其成员类型所占用的最大字节大小相同。

对于联合体的使用,日后进行补充。

三.枚举类型

枚举是 C 语言中的一种基本数据类型,用于定义一组具有离散值的常量,它可以让数据更简洁,更易读。

枚举类型通常用于为程序中的一组相关的常量取名字,以便于程序的可读性和维护性。

枚举类型的变量定义与结构体相似,其关键字为enum。

#include <stdio.h>
enum number{
    zero,one,two,three,four
};
int main() {
    enum number a;
    a = zero;
    printf("%d\n", a);
    a = one;
    printf("%d\n", a);
    a = two;
    printf("%d\n", a);
    a = three;
    printf("%d\n", a);
    a = four;
    printf("%d\n", a);
    return 0;
}

对于枚举类型内部的成员,其值从0开始累加,如上述代码中枚举结果就是

0
1
2
3
4

当给其成员赋值时,在其之后的值就从该成员开始累加,例如,two = 10时,其结果为

0
1
10
11
12

那枚举类型用什么用途呢?

首先,他可以实现数组自动扩容。

可以看这篇文章。

http://t.csdnimg.cn/oPdd0

其次,他可以增加程序的可读性和辅助程序的作用。

例如,我们想要输出彩色文字时,可以采用如下方法:

printf("\033[+参数1+:+参数2+:+参数3+m + 内容 + \033[0m");

1.通用格式控制:

0:重置所有属性

1:高亮/加粗

2:暗淡

4:下划线

5:闪烁

7:反转

8:隐藏

2.背景色:

40:黑

41:深红

42:绿

43:黄色

44:蓝色

45:紫色

46:深绿

47:白色

3.前景色

30:黑

31:红

32:绿

33:黄

34:蓝色

35:紫色

36:深绿

37:白色

#include <stdio.h>
int main() {
    printf("\033[1;32;43mhello world\033[0m");
    return 0;
}

但是上述方法可读性低,我们可以利用枚举类型封装字体颜色工具

#include <stdio.h>
enum color{
    RED = 31,
    GREEN,
    YELLOW,
    BLUE
};

#define COLOR_SET "\033[1;%dm"
#define COLOR_END "\033[0m"
int main() {
    printf(COLOR_SET "hello world\n" COLOR_END, RED);
    printf(COLOR_SET "hello world\n" COLOR_END, GREEN);
    printf(COLOR_SET "hello world\n" COLOR_END, YELLOW);
    printf(COLOR_SET "hello world\n" COLOR_END, BLUE);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值