您的位置:首页 > 编程语言 > C语言/C++

由C语言位域(冒号)谈C语言的结构体、枚举、共用体

2015-08-19 17:02 302 查看

综述

今天看到一行代码

unsigned char busy:1;

不太明白 : 的作用,百度了几分钟,发现是结构体中位域操作符,深感平时工作疏于学习,以至于这么简单的问题还不知道,所以写了这篇文章,以作为复习。

1、关于位域

有些信息在储存时,并不需要占用一个完整的字节,而只需占几个或一个二进制位,例如存放一个开关常量,只有0和1两种状态,用一个二进制位即可满足要求,无需浪费空间,并且可以使处理更加简便,所以C语言提供了一种数据结构,成为位域(或位段)。这样就可以把几个不同的对象用一个字节的二进制位域来表示。所谓“位域”就是是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。

每一个域有一个域名,允许在程序中按域名进行操作。位域主要用于结构体。

struct temp  
{  
int a:8;  
int b:2;  
int c:6;  
}data; 
在上面的代码中,data占2个字节。位域的两个特点如下:

1.1. 一个位域必须存储在同一个字节中,不能跨两个字节。如果一个字节所剩空间不够存放另一个位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:

struct temp
{
char a:4
char :0         //空域
char b:4       //从下一单元开始存放
char c:4
}
其中,a占第一个字节的4位,后4位填零不用,b从第二个字节开始,占4位,c占剩下4位。

1.2. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:

struct temp
{
char a:4
char  :2        //空域
char b:4       //从下一单元开始存放
char c:4
}


2、结构体

2.1、存在理由

描述一组具有相同类型数据的有序集合,用于处理大量相同类型的数据运算 使用构造类型——数组

描述一组具有不同类型数据的有序集合,用于处理大量不同类型的数据运算 使用构造类型——结构体

2.2、定义方式

2.2.1、先声明结构体类型再定义变量名

struct stu
{
成员列表
};
struct stu Lucy;


2.2.2、在声明类型的同时定义变量

struct stu
{
成员列表
}Lucy;


2.2.3、直接定义结构体类型变量,无类型名

struct
{
成员列表
}Lucy,Bob;
在上面三种定义结构体变量的方式中,stu为结构体类型名(第三种没有类型名),Lucy为结构体变量名。可以同时变量多个结构体变量名(如第三个)。

结构体类型名:指定了一个结构体类型(相当于char),它相当于一个模型,但其中并无具体数据,系统对之也不分配实际内存单元。

结构体变量名:实际分配空间——为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。

我们推荐使用如下方法(使用typedef重命名)其中STU为结构体类型名,Lucy与Bob为结构体变量名:

typedef struct student
{
int num;
char name[20];
char sex;
}STU;
STU Lucy,Bob;


2.4、注意事项

2.4.1、结构体变量的成员引用必须单独引用

结构体变量名.成员名

如:

Lucy.num = 101;
scanf("%c",&Lucy.sex);
printf("%s",Lucy.name);
2.4.2、允许具有相同类型的结构体变量相互赋值(多用于结构体成员整体操作,例如排序等)

Bob = Lucy;
2.4.3、结构体可以在定义的时候进行初始化

STU Lucy = {12, "hello", 'm'};
3.4、允许嵌套定义结构体变量,成员引用多级引用

Lucy.birthday.mouth = 12;
关于结构体数组和结构体指针等深层次用法,在中介绍,此处不做赘述!

3、共用体

3.1、存在理由和特点

a.同一内存段可以用来存放几种不同类型的成员,但每一瞬间只有一种起作用

b.共用体变量中起作用的才成员是最后一次存放的成员,在存入一个新的成员后原有成员的值会被覆盖

c.共用体变量的地址和它的个成员的地址都是同一地址

3.2、定义方式

和结构体非常类似,有三种定义方式,我们推荐下面这种:

typrdef union data
{
short int i;    //短整型:2个字节
char ch;        //字符型:1个字节
float f;        //实型:4个字节
}DATA;
DATA a,b;
a.i——>引用共用体变量中的整型变量i

a.ch——>引用共用体变量中的整型变量ch

a.f——>引用共用体变量中的整型变量f

3.3、参考代码

#include<stdio.h>

//共用体
typrdef union data

{

long int x;  //长整型:4个字节
char y;      //字符型:2个字节
int z;      //整型:4个字节
}DATA;
DATA a = {10};

int mian()
{
a.x = 5;
a.y = 6;
a.z = 15;
printf("%d\n",a.x + a.y);
return 0;
}


分析:

初始化为10(后面的修改只改变了一个字节)

10 0000 1010

5 0000 0101

6 0000 0110

15 0000 1111

打印结果是30,因为初始化和修改共用体元素,都是单位覆盖。因而这里无论是4字节的a.x还是1字节的a.y都是15,打印的结果为30(共用体所占的字节是最大的元素,也就是这个结构体占4字节)。

4、枚举

4.1、存在理由

有的时候我们需要几种可能的值(我们也可以用define来获得,或者使用const类型的变量),或者我们需要这几个变量自动的那规律来变化(如何变化见下面),比如,我们的定义中是一周7天,或者我们需要12中颜色,我们就可以使用枚举。枚举是将变量的值一一列举出来,变量的值只限于列举出来的值的范围。

4.2、定义方式

同样的枚举我们推荐用下面的定义方式

typrdef enum week	//枚举类型
{
mon,tue,wed,thu,fri.sat,sun
}WEEK;
WEEK workday、weekday;    //枚举变量
其中week为枚举类型名,WEEK为枚举变量名,mon,tue,wed,thu,fri.sat,sun为枚举值表,workday、weekday为枚举变量,workday与weekday只能取sun...sat中的一个。

workday = mon; //正确

weekday = tue; //正确

workday = abc; //错误,枚举中没有abc

如果没有初始化(注意下面的写法是不规范的),那么

mon = 0

tue = 1

wed = 2

...

sun = 6

我们也可以初始化

mon = -1

那么

tue = 0

wed = 1

...

sun = 5

或者我们也可以初始化

mon = 0

tue = 0

那么

wed = 1

...

sun = 5

我们可以看到,从没有定义的那个元素开始逐次增加,本质上enum是整数型(如果是java, 则不是整数型,而是一个由编译器生成的特殊的类)。

4.3、注意事项

a.枚举值是常量,不能在程序中用赋值语句对它赋值,例如sun = 5; mon = 2; sun = mon;都是错误的。

b.可以改变枚举值的默认值(上面的初始化就是这种方式),如:

enum week
{
mon = 3; tue,wed,thu,fri.sat,sun
};
那么mon等于3,tue等于4,以此类推。

4.4、事例代码

#include<stdio.h>

//枚举
typrdef enum week	//枚举类型
{
sun = 2,mon,tue,wed,thu,fri.sat
}WEEK;

WEEK a,b,c;//枚举变量

enum bool
{
false,true
}bl;

int main()
{
a = sun;
b = mon;
c = ture;
printf("%d, %d, %d",a, b, c);
bl = ture;
if(1 == bl)
{
printf("bl为真\n");
}
return 0;
}
打印结果为:2,3,4bl为真。

5、结束语

结构体、共用体、枚举都是构造类型数据,我们从定义方式就可以看到他们的相似性。在结构体类型中的位段使用是值得我们注意的,如果用好了,会使我们在项目中节省很多必要的空间!【END150613】

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

版本:V1.1

时间:2015.09.19

作者:Alan

说明:修改部分错误和修改排版

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

版本:V1.0

时间:2015.06.13

作者:Alan

说明:完成文章。

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: