C语言联合,枚举,位段

目录

一,联合

1,创建联合体

2,初始化联合体

3,使用联合体

3.1普通用法

3.2指针用法

4,匿名联合

4.1匿名结构体

4.2匿名联合体

二,枚举

1.定义

2.赋值

3.枚举的优点

三,位段

1.位段的定义

2.位段的内存分配

3.位段的跨平台问题

4.位段注意事项


一,联合

是一种数据类型,能在同一块空间中存储不同类型的数据(不是同时存储)。

1,创建联合体

与创建结构体相同

union stu{
  int age; 
  char name;
  double gread; 
};
//虽然联合内有很多类型,但当声明之后只能存储一个类型

//声明stu 类型的相关变量
union stu s;      // stu类型的联合变量
union stu arr[2]; //内含两个联合变量的数组 
union stu *p;     //指向stu类型联合的指针

声明s时,编译器分配空间,分配的空间能存储声明中占用最大的字节类型(例子中为double类型)

2,初始化联合体

联合体只能存储一个值

方法一:把一个联合体初始化为另一个同类型的联合体

方法二:初始化联合的第一个元素

方法三:使用指定初始化器

union stu s1;
union stu s2;  
s2.age = 18;
s1 = s2;                      //用同类型联合初始化
union stu s3 = { 20 };        //初始化第一个元素age
union stu s4 = { .age = 18 }; //指定初始化器

3,使用联合体

3.1普通用法

union stu s ;
s.age = 18 ;     //把18存储在age,占用4字节
s.name = 'r' ;   //清楚上述 18 ,存储r ,占用1个字节
s.gread = 59.5 ; //清楚上述 r ,存储59.5,占用8个字节

 点(.)运算符表示正在使用哪种数据类型,在联合体中,一次存储一个值。即使有足够的空间,也不能同时存储两个类型的值。

3.2指针用法

当然也可以通过指针使用联合:

union stu
{
	int age;
	char name;
	double gread;
}s;
union stu* p = &s;
s.age = 18;
int x = p->age; //相当于 s.age

注意:使用联合体时要注意不要用错,比如:

         s.age = 20 ; //这里存储的是age的内容

        int x =s.gread  / 100 ; //但是这里使用的是 gread的内容,这样做是错误的 

4,匿名联合

4.1匿名结构体

匿名结构体就是没有名称的结构体内容

struct 
{
  char name[20];
  int age;
  char id[20];
};

4.2匿名联合体

和匿名结构体类似,是一个没有名称的联合体

union
{
  int age;
  char id;
  double gread;
};

二,枚举

 这一通过枚举类型声明符号名称来表示整型常量,使用关键字enum。

enum常量是int类型,所以只要能使用int类型的地方就可以使用枚举类型

1.定义

enum color //声明枚举类型
{
  red,      // 0 默认值
  green,    // 1
  blue     // 2
};
//从上到下 默认递增 1

red,green,blue这些被称为枚举符,默认为int类型的值,所以枚举常量可以在switch语句中作为标签。

2.赋值

enum color //声明枚举类型
{
  red ,    //默认值 0
  green  , // 1
  blue  = 200 ,   
  yellow,   //从上到下递增1 所以yellow是201
  orange    //orange 是202
};

如果只给一个枚举常量赋值,没有对后面的枚举常量赋值,那么后面的枚举常量就是被赋予的值 的后续值;第一个如果没有被赋值仍然是默认值0。

3.枚举的优点

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较,枚举有类型检查(int类型),更加严谨
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次性可以定义多个常量

三,位段

1.位段的定义

位段类似于结构体,但是两点不同:

  1. 位段的成员必须是 int ,unsigned int ,signed int ,char;
  2. 位段的成员名后面有一个冒号和一个数字
struct A
{
  int a : 2 ;  //a成员占 2 个 bit位
  int b : 3 ;
  int   : 4 ; //没有指定名称的位段
}s;

冒号后面为指定的成员所占内存长度 ,需要注意的是这个长度不能超过该类型所能表示的最大长度,这个长度表示二进制长度

比如32位机中,int占用32位,所以int 类型被指定的长度不能超过32 ;

对上述位段进行赋值操作观察其打印的值: 

 打印值时我们发现 a,b 正数的15变成了,输出的时候变成了-1,而c没有变这是为什么?

2.位段的内存分配

VS编译器中是从右向左,剩余内存不够,浪费掉

1:位段的空间是按照需要以四个字节(int)或者 一个字节(char)的方式开辟的 

2:位段涉及很多不确定因素,位段是不可以跨平台的,注重移植的程序应该避免使用位段

3:上述代码中没有指定名称的位段是无法进行访问的,但计算位段大小时仍会计算在内。

3.位段的跨平台问题

  1. int位段被当成有符号数还是无符号数是不确定的
  2. 位段中最大位的数,不能确定,如:16位机器中最大16位,32位机器中最大32,写成26在16位机器中是会报错的
  3. 位段中的成员在内存中从左向右分配还是从右向左分配标准是没有定义的
  4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳与第一个位段所剩余的位时,是舍弃剩余的位,还是利用的,不确定

4.位段注意事项

  1. 位段所占的位数,不能超过该类型的最大位数
  2. 在位段里,不给位段起名字将不能访问该位段,但是计算内存大小时任然会将该位段算在内(sizeof())计算。
  3. 不可以对位段进行取地址操作
  4. 如果位段被赋值的二进制位数大于位段自身的大小时,在使用时会发生截断问题,截断后的最高位表示符号位。当位段类型定义是无符号类型时,将不会有变成负数这个问题
  5. 使用位段时应该注意程序是否注重可移植性

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
C语言中,结构体是一种自定义数据类型,可以将不同类型的变量组合在一起,形成一个新的数据类型。结构体定义的基本形式如下: ```c struct 结构体名 { 数据类型 成员名1; 数据类型 成员名2; // ... }; ``` 其中,结构体名是用户自定义的名称,成员名是结构体中每个成员的名称,数据类型可以是任意C语言的数据类型,包括基本数据类型和自定义数据类型。 结构体变量的定义方式如下: ```c struct 结构体名 变量名; ``` 读取结构体中的成员变量可以通过“.”运算符来实现,例如: ```c #include <stdio.h> struct Person { char name[20]; int age; }; int main() { struct Person p; printf("请输入姓名:"); scanf("%s", p.name); printf("请输入年龄:"); scanf("%d", &p.age); printf("姓名:%s,年龄:%d\n", p.name, p.age); return 0; } ``` 枚举是一种特殊的数据类型,用于定义一组常量。枚举的定义方式如下: ```c enum 枚举名 { 常量名1, 常量名2, // ... }; ``` 其中,枚举名是用户自定义的名称,常量名是枚举中每个常量的名称。枚举常量的值默认是从0开始自动递增的,也可以手动指定值。例如: ```c #include <stdio.h> enum Weekday { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }; int main() { enum Weekday today = Tuesday; printf("今天是星期%d\n", today + 1); return 0; } ``` 联合是一种特殊的数据类型,它的成员变量共享同一块内存空间。联合的定义方式如下: ```c union 联合名 { 数据类型 成员名1; 数据类型 成员名2; // ... }; ``` 其中,联合名是用户自定义的名称,成员名是联合中每个成员的名称,数据类型可以是任意C语言的数据类型,但所有成员的大小不能超过联合的大小。例如: ```c #include <stdio.h> union Number { int i; float f; }; int main() { union Number n; n.i = 123; printf("int: %d, float: %.2f\n", n.i, n.f); n.f = 3.14; printf("int: %d, float: %.2f\n", n.i, n.f); return 0; } ``` 以上就是C语言中自定义数据类型中的结构体、枚举联合的基本用法和注意事项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值