C语言第八章位域

上传人:hs****ma 文档编号:568769016 上传时间:2024-07-26 格式:PPT 页数:22 大小:373.50KB
返回 下载 相关 举报
C语言第八章位域_第1页
第1页 / 共22页
C语言第八章位域_第2页
第2页 / 共22页
C语言第八章位域_第3页
第3页 / 共22页
C语言第八章位域_第4页
第4页 / 共22页
C语言第八章位域_第5页
第5页 / 共22页
点击查看更多>>
资源描述

《C语言第八章位域》由会员分享,可在线阅读,更多相关《C语言第八章位域(22页珍藏版)》请在金锄头文库上搜索。

1、第八章位域,联合,枚举,定义类型及预处理功能制作人 计科一班 王建政目录位域及结构嵌套位域及结构嵌套 联合联合联合联合枚举枚举定义类型名定义类型名预处理功能预处理功能21.1位域m位域是结构成员的特殊形式,它需要定义位的长度,它是整型数存储区中相连的位的集合。通过位域可以方便的用成员访问小于一个字节的存储区。m它的一般形式为:m struct 结构名m m 类型 变量名 1:长度;m 类型 变量名 1:长度;m .m 31.1位域其中,冒号:表示使用的是位域,其后的长度表示需要分配的存储单元位数。其中,冒号:表示使用的是位域,其后的长度表示需要分配的存储单元位数。域变量必须定义为域变量必须定义

2、为intint或或unsigned.unsigned.位域变量有某些限制。比如,不能去一个位域变量的地址;不允许超越整型量边界。位域变量有某些限制。比如,不能去一个位域变量的地址;不允许超越整型量边界。例:例: 下面定义非法:下面定义非法: struct flg struct flg unsigned flag1:8; unsigned flag1:8; unsigned flag2:12; unsigned flag2:12; fcode; fcode;这里,这里,flag1flag1和和flag2flag2的位数超越整型(的位数超越整型(1616位)的边界。应该写成;位)的边界。应该写成;

3、 struct flg struct flg unsigned flag1:8; unsigned flag1:8; unsigned: 0; unsigned: 0; unsigned flag2:12; unsigned flag2:12; fcode; fcode;这里,第二个成员省略位域变量名,其长度说明为这里,第二个成员省略位域变量名,其长度说明为0.0.表示该位域变量后面定义的位域表示该位域变量后面定义的位域从下一个字边界开始存放。从下一个字边界开始存放。41.2结构嵌套wokername10agewagepayday结构成员不仅可以是位数可变的位域变结构成员不仅可以是位数可变的位

4、域变量,而且可以是另一个结构类型变量。量,而且可以是另一个结构类型变量。这种情况被称为嵌套式结构。这种情况被称为嵌套式结构。例如例如: 下面的结构变量下面的结构变量payday就是嵌套在结就是嵌套在结构构person内的一个嵌套式结构变量。内的一个嵌套式结构变量。 struct date int month; int day; int year; ;struct person char name10; int age; float wage;struct date payday;woker;monthdayyear成员变量成员变量成员变量成员变量成员变量成员变量结构成员变量结构成员变量子成员子

5、成员子成员子成员子成员子成员51.2结构嵌套如果要给如果要给woker的各成员赋值,可以使用下面程序段:的各成员赋值,可以使用下面程序段: 显然对每个结构成员的访问,在结构嵌套情况下,必须从最外到最内层逐个列出结构显然对每个结构成员的访问,在结构嵌套情况下,必须从最外到最内层逐个列出结构成员变量名。成员变量名。在定义时可以用同样的方法赋初值。在定义时可以用同样的方法赋初值。 woker=Li_ming,34,350,11,1,1993;woker.payday.year=199362.1联合 联合是一种与结构相类似的构造类型,联合与结构一样,可以包括不同类型和长度联合是一种与结构相类似的构造类

6、型,联合与结构一样,可以包括不同类型和长度的数据。的数据。联合与结构的主要区别在于,联合与结构的主要区别在于, 联合类型变量所占用空间不是各个成员所需联合类型变量所占用空间不是各个成员所需空间字节数的总和,而是联合成员中需要空间最大的成员的字节数。空间字节数的总和,而是联合成员中需要空间最大的成员的字节数。定义联合类型的一般形式:定义联合类型的一般形式: union 联合名联合名 类型类型 变量名;变量名; 类型类型 变量名;变量名; . 联合变量;联合变量; 例如,定义一个名为例如,定义一个名为datadata的联合,并说明的联合,并说明valuevalue为联合变量,这个变量在不同时刻,为

7、联合变量,这个变量在不同时刻,可以是一个字符(可以是一个字符(1byte1byte), ,一个短整型(一个短整型(2byte2byte), ,一个长整型(一个长整型(4byte4byte)。定义如下)。定义如下union dataunion data char ch; char ch; short num; short num; long lnum; long lnum;value;value;72.1联合valuechnumlnum内存区域内存区域共享起始位置共享起始位置共共享享存存储储空空间间对于上述定义,当编译程序编译时看到对于上述定义,当编译程序编译时看到关键字关键字union,它扫视

8、联合定义中的成员它扫视联合定义中的成员类型表,类型表,找出要求占用的最大存储空间找出要求占用的最大存储空间的一个成员,并以这个成员所需的存储的一个成员,并以这个成员所需的存储空间作为分配给联合变量的存储空间空间作为分配给联合变量的存储空间,以保证能存放任何一个成员数据。以保证能存放任何一个成员数据。 为了访问联合的成员,可以使用与结构相同的方法,即使用句号运算符为了访问联合的成员,可以使用与结构相同的方法,即使用句号运算符“.或箭或箭头头“-。如果直接对联合变量进行操作,使用。如果直接对联合变量进行操作,使用“。”,若联合变量通过一个指针来,若联合变量通过一个指针来访问,使用箭头运算符。例如:

9、访问,使用箭头运算符。例如: value.num=100; value.num=100; 此时,联合变量为一个整型变量。此时,联合变量为一个整型变量。 value.ch=a; value.ch=a;此时,联合变量为一个字符变量。此时,联合变量为一个字符变量。 由于由于valuevalue是一个共享变量。是一个共享变量。因此在变成是必须记住在联合中当前存储的是什么样因此在变成是必须记住在联合中当前存储的是什么样的数据类型。如果要进行数值计算,那么用法要前后一致,即取回的类型一定是最的数据类型。如果要进行数值计算,那么用法要前后一致,即取回的类型一定是最近才存放的类型。近才存放的类型。如果以一种类

10、型存放,而以另一种类型取出,则可能发生错误。如果以一种类型存放,而以另一种类型取出,则可能发生错误。8联合应用举例 必须指出,利用联合变量的各个成员共享公共存储区的特点,在程序设计中,可方必须指出,利用联合变量的各个成员共享公共存储区的特点,在程序设计中,可方便的进行数据的交换和处理。下面的程序就是一个类似的例子。程序把用十六进制数便的进行数据的交换和处理。下面的程序就是一个类似的例子。程序把用十六进制数表示的整型数(占两个字节)的低位和高位字节相互交换。表示的整型数(占两个字节)的低位和高位字节相互交换。例例8.4 交换用十六进制数表示的整型数的低位和高位字节。交换用十六进制数表示的整型数的

11、低位和高位字节。 #include void main() union body /定义了定义了a和和b为联合变量为联合变量 /联合变量包括两个成员,一个结构变量联合变量包括两个成员,一个结构变量byte,它包括了表它包括了表 struct BYTE /示一个整型数的低位字节和高位字节示一个整型数的低位字节和高位字节l和和h。另一个为无。另一个为无 /符号数符号数word. unsigned char l,h; byte; unsigned int word; a,b; printf(Enter data?); /a.byte.ha.byte.h和和a.byte.la.byte.l分别取至分别

12、取至wordword变量中读入的高位字节和低变量中读入的高位字节和低 scanf(%x,&a,word); /位字节。把联合变量位字节。把联合变量a的两个成员的两个成员a.byte.l和和a.byte.h的值分别的值分别b.byte.h=a.byte.l; /赋给了联合变量赋给了联合变量b的两个成员的两个成员b.byte.h和和b.byte.l,当最后一个,当最后一个b.byte.l=a.byte.h; /语句输出时,在语句输出时,在b.word中已经交换过数据了中已经交换过数据了9联合应用举例printf(%x-%xn,a.word,b.word);程序运行结果:程序运行结果: Enter

13、date? 3a6e 3a6e-6e3a 3.1枚举枚举 通过列举一系列由用户自通过列举一系列由用户自己确定的有序标识符己确定的有序标识符所定义的类型叫枚举类型。标识符名所定义的类型叫枚举类型。标识符名称代表一个称代表一个数据值数据值,期间又先后次序,期间又先后次序,可以进行比较可以进行比较,通常把标识符称为枚举类型的,通常把标识符称为枚举类型的元素。元素。 枚举类型在日常生活中十分常见,它采用比较接近人类自然语言的方式表示有关信枚举类型在日常生活中十分常见,它采用比较接近人类自然语言的方式表示有关信息,以提高程序的可读性。比如,颜色有红黄绿;每周的天数有星期日,星期六。息,以提高程序的可读性

14、。比如,颜色有红黄绿;每周的天数有星期日,星期六。103.1枚举 枚举和结构一样,都是自定义的一种数据类型。美据用关键字枚举和结构一样,都是自定义的一种数据类型。美据用关键字enumenum表示。定义枚举表示。定义枚举类型的一般形式为:类型的一般形式为:enum 枚举名枚举名 枚举表枚举表;例如:例如:下面程序段定义一个称为下面程序段定义一个称为color的枚举类型,并说明的枚举类型,并说明col是属于这种类型的变量。是属于这种类型的变量。 enum color black,bllue,red,green,white; enum color col;给出上述定义后,枚举变量给出上述定义后,枚举

15、变量col可以去且只能取枚举中任何一个标识符,利用这个变可以去且只能取枚举中任何一个标识符,利用这个变量,下面的语句都是有效的。量,下面的语句都是有效的。 col=blue; if(col=blue) 处理处理blue的颜色的程序块;的颜色的程序块; 如果:如果:col=yellow;则:该赋值语句将产生错误,因为则:该赋值语句将产生错误,因为yellow不再列举出来的枚举值中。不再列举出来的枚举值中。11枚举对枚举类型的定义及变量的使用,其实只是编译程序将枚举中的对枚举类型的定义及变量的使用,其实只是编译程序将枚举中的每个标识符按次序每个标识符按次序用他们所对应的整型数代码来代替用他们所对应

16、的整型数代码来代替,再不进行初始化的情况下,第一个枚举标识符,再不进行初始化的情况下,第一个枚举标识符的代码值为的代码值为0,第二个为,第二个为1,以此类推。,以此类推。col=blue;blue不是字符串,它代表一个整型数,也不能将不是字符串,它代表一个整型数,也不能将col按字符形式输出按字符形式输出“blue”如果要改变缺省值进行初始化。可以通过在标识符后加一个赋值符号和一个整型量来如果要改变缺省值进行初始化。可以通过在标识符后加一个赋值符号和一个整型量来实现。例如:实现。例如: enum colorblack,blue,red=5,green,white; enum colorblac

17、k,blue,red=5,green,white; 现在,这些标识符对应的整型数为:现在,这些标识符对应的整型数为: black 0 black 0 blue 1 blue 1 red 5 red 5 green 6 green 6 white 7 white 7123.2定义类型名-typedefc c语言允许用户使用关键字语言允许用户使用关键字typedef,typedef,为已有的类型定义一个新的名字。例如:为已有的类型定义一个新的名字。例如:typedef int integer;typedef int integer;该语句使名字该语句使名字integerinteger与标准类型与标

18、准类型int int 成为同义。成为同义。定义类型的一般形式为:定义类型的一般形式为: typedef typedef 类型类型 定义名;定义名;同样,使用同样,使用typedef char chr;typedef char chr;语句可以建立字符类型语句可以建立字符类型charchar的新定义名的新定义名chr:chr:也可以用也可以用typedeftypedef为结构与联合等复杂的数据类型建立定义名。例如:为结构与联合等复杂的数据类型建立定义名。例如:struct birth_datestruct birth_date char name10; char name10; int mont

19、h; int month; int day; int day; int year; int year; typedef struct birth_date birthday;typedef struct birth_date birthday;这里,把已定义的结构类型这里,把已定义的结构类型struct birth_datestruct birth_date改为定义名改为定义名birthday.birthday.利用定义名利用定义名birthday,birthday,则可以定义该结构类型的变量。则可以定义该结构类型的变量。13小结小结1.数组是处理同种类型数据的结合体。数组是处理同种类型数据的

20、结合体。2.结构是一种归在同一名字下具有关联的不同类型变量的结合,结构是一种归在同一名字下具有关联的不同类型变量的结合,也可以成为不同数据类型的结合体。也可以成为不同数据类型的结合体。3.位域是允许按位访问结构成员的一种结构变体。位域是允许按位访问结构成员的一种结构变体。4.联合是两个或两个以上不同类型的变量公用同一内存空间的联合是两个或两个以上不同类型的变量公用同一内存空间的共享体。共享体。5.枚举是一个自定义的有序标识符表。枚举是一个自定义的有序标识符表。关键字关键字typedef不能定义一种新的数据类型,但可以为已存在不能定义一种新的数据类型,但可以为已存在的数据类型产生一个新的定义名。

21、的数据类型产生一个新的定义名。144预处理功能 通过预处理程序控制行有效的扩充语言能力,是通过预处理程序控制行有效的扩充语言能力,是c c语言的有一个特色。语言的有一个特色。c c语言预处语言预处理功能是由与处理程序实现的。理功能是由与处理程序实现的。c c语言的预处理程序负责分析和处理以语言的预处理程序负责分析和处理以“# #”为首字母为首字母的预处理控制行。预处理控制行主要有宏替换,文件包含和条件编译。由于与处理是的预处理控制行。预处理控制行主要有宏替换,文件包含和条件编译。由于与处理是在编译程序开始工作之前进行的,所以把执行预处理功能的这部分程序称为预处理程在编译程序开始工作之前进行的,

22、所以把执行预处理功能的这部分程序称为预处理程序。序。 从语法角度看,预处理控制行并不是真正属于从语法角度看,预处理控制行并不是真正属于c c语言的语句,他们可以出现在程序语言的语句,他们可以出现在程序代码的任何地方,在他们的出现点后开始有效,通常宏替换和文件包含出现在文件的代码的任何地方,在他们的出现点后开始有效,通常宏替换和文件包含出现在文件的开头。与预理控制行的作用范围仅限于说明他们的文件,超出了那个文件就失去作用。开头。与预理控制行的作用范围仅限于说明他们的文件,超出了那个文件就失去作用。 恰当地使用恰当地使用c c语言的预处理功能,扩展了语言的预处理功能,扩展了c c语言程序的编程环境

23、,可以编写出易读语言程序的编程环境,可以编写出易读易改,便于移植和调试的易改,便于移植和调试的c c程序,有利于软件工程的模块化设计。程序,有利于软件工程的模块化设计。4.1宏替换宏替换-#define用用#define作为标志的预处理命令不仅可定义符号常量及字符串,而且也可定义带参作为标志的预处理命令不仅可定义符号常量及字符串,而且也可定义带参数的宏。数的宏。151.简单的字符串替换 宏替换命令宏替换命令#define#define用来定义一个宏标识符和一个字符串,在程序中每次遇到该标用来定义一个宏标识符和一个字符串,在程序中每次遇到该标识符,就用所定义的字符串替换,这个标识符也叫宏替换名。

24、替换过程称为宏替换。识符,就用所定义的字符串替换,这个标识符也叫宏替换名。替换过程称为宏替换。宏替换命令的一般形式是:宏替换命令的一般形式是: #define #define 宏标识符宏标识符 字符串字符串 其中,宏标识符通常用大写字母表示,以便于程序中其他变量名相区别,明显地其中,宏标识符通常用大写字母表示,以便于程序中其他变量名相区别,明显地标志出程序中需要宏替换的地方,读程序是更加醒目。标志出程序中需要宏替换的地方,读程序是更加醒目。 #define #define,宏标识符,字符串各部分之间用空格分割,其末尾不带分号,以换行结,宏标识符,字符串各部分之间用空格分割,其末尾不带分号,以换

25、行结束。每行只能定义一个预处理行。例如束。每行只能定义一个预处理行。例如: : 程序的开头,有程序的开头,有#define N 10#define N 10宏替换命令。宏替换命令。为进一步说明宏替换仅是简单的用所定义的字符串来替换对应的宏标识符的过程,各为进一步说明宏替换仅是简单的用所定义的字符串来替换对应的宏标识符的过程,各处定义一个标准出错信息并输出的例子:处定义一个标准出错信息并输出的例子: #define E_MS standard error On inputn #define E_MS standard error On inputn printf(E_MS); printf(E_

26、MS);预处理程序在遇到标识符预处理程序在遇到标识符E_MSE_MS时,用定义的字符串来替换。对编译程序来说。时,用定义的字符串来替换。对编译程序来说。printfprintf()()语句的实际形式是:语句的实际形式是: printf(standard error On inputn); printf(standard error On inputn);162.带参宏定义及宏调用 宏替换命令宏替换命令#define#define还有一个重要的特点,即宏标识符像函数一样可以带有还有一个重要的特点,即宏标识符像函数一样可以带有形式时参数。在程序中用到宏标识符是,实际参数都将代替这些形式参数,形式时

27、参数。在程序中用到宏标识符是,实际参数都将代替这些形式参数,使用更灵活。带参数宏定义的一般形式是:使用更灵活。带参数宏定义的一般形式是: #define #define 宏标识符(参数表)宏标识符(参数表) 表达式表达式 宏标识符就是带参数宏的名字。参数表中的参数类似于函数中的形式参数宏标识符就是带参数宏的名字。参数表中的参数类似于函数中的形式参数; ;宏标识符与左圆括号之间不能有空格;表达式是用于替换的表达式。宏标识符与左圆括号之间不能有空格;表达式是用于替换的表达式。 宏调用的一般形式是:宏调用的一般形式是: 宏标识符(参数表)宏标识符(参数表)此处的红标识符是已被定义的宏标识符;参数表中

28、的参数类似于函数中的实此处的红标识符是已被定义的宏标识符;参数表中的参数类似于函数中的实参数。参数。3.3.定义宏的情况定义宏的情况 要求两个数中较大数要求两个数中较大数 #define MAX(a,b)(ab)?a:b#define MAX(a,b)(ab)?a:b17程序举例#include#include#define MAX(a,b)(a,b)?a:b#define MAX(a,b)(a,b)?a:bvoid mainvoid main int x,y; int x,y; x=10; x=10; y=20; y=20;printf(the maximum data is %d,MAX(

29、x,y);printf(the maximum data is %d,MAX(x,y); 程序运行结果:程序运行结果: the maximum data is 20 the maximum data is 20程序说明:程序说明:在编译时,预处理程序先扫描源程序,当发现标识符在编译时,预处理程序先扫描源程序,当发现标识符MAXMAX并且后跟一对带有并且后跟一对带有参数的圆括号时,就用表达式替换该名字,同时用实参数参数的圆括号时,就用表达式替换该名字,同时用实参数x,yx,y替换参数替换参数a,b.printfa,b.printf()()语句被代换为如下形式:语句被代换为如下形式: printf

30、(the maximum data is %d,(x,y)?x:y); printf(the maximum data is %d,(x,y)?x:y);18宏的撤销 宏一旦被定义,在其所在的文件中均是存在和可见的,这一点很像外部变宏一旦被定义,在其所在的文件中均是存在和可见的,这一点很像外部变量。如果要对某一个宏定义撤销,可用如下预处理命令:量。如果要对某一个宏定义撤销,可用如下预处理命令: #undef #undef 宏标识符宏标识符一旦消除了原来的定义,这个宏标识符可以重新被定义。一旦消除了原来的定义,这个宏标识符可以重新被定义。/*/*程序实例程序实例*/*/#include#incl

31、ude#define SWAP(a,b,t) t=b;b=a;a=t#define SWAP(a,b,t) t=b;b=a;a=tvoid main()void main() int a,b,c;int a,b,c;printf(Enter two integer a,b: );printf(Enter two integer a,b: );scanf(%d %d,&a,&b);scanf(%d %d,&a,&b);SWAP(a,b,c);SWAP(a,b,c);printf(Exchanged:a=%d,b=%dn,a,b);printf(Exchanged:a=%d,b=%dn,a,b);

32、 程序运行结果:程序运行结果: Enter two integer a,b:25 35 Enter two integer a,b:25 35 Excahnged:a=35 ,b=25 Excahnged:a=35 ,b=2519包含文件-#include“包含文件包含文件”处理是使用处理是使用#include#include命令把给定的包含文件的内容嵌入到另一命令把给定的包含文件的内容嵌入到另一个源程序中。其一般形式是:个源程序中。其一般形式是: #include #include文件名文件名 或或#include#include 为了使编写的程序清晰易读,通常可以把常数和宏定义编写进为了使

33、编写的程序清晰易读,通常可以把常数和宏定义编写进includeinclude文文件中,并通过件中,并通过#include#include预处理命令放入任何源文件。预处理命令放入任何源文件。includeinclude文件也可以用文件也可以用于包含外部变量和复杂数据类型定义的说明,所需要的类型仅需要在于包含外部变量和复杂数据类型定义的说明,所需要的类型仅需要在include include 文件中定义和命名一次。文件中定义和命名一次。 这种位于文件开始部分的被包含文件通常称为这种位于文件开始部分的被包含文件通常称为“标题文件标题文件”或或“头文件头文件”,并以,并以“h h”作为后缀。如作为后缀

34、。如c c标准库函数的各种标准库函数的各种“头文件头文件”。 #include #include预处理命令的实质是,告示预处理程序将包含文件的内容嵌入到预处理命令的实质是,告示预处理程序将包含文件的内容嵌入到原文件中原文件中#include#include出现的地方。其一般形式是如下图。出现的地方。其一般形式是如下图。 需要嵌入的包含文件的存放地点,必须有文件的路径和文件名指定,并且需要嵌入的包含文件的存放地点,必须有文件的路径和文件名指定,并且被放在双引号内,系统预定现在应用包含文件的原文件所在的目录中查询,被放在双引号内,系统预定现在应用包含文件的原文件所在的目录中查询,若找不到,再按系统指定的标准方式向外查找,如果已经知道被包含文件不若找不到,再按系统指定的标准方式向外查找,如果已经知道被包含文件不在当前工作目录,可以使用尖括号形式查找。在当前工作目录,可以使用尖括号形式查找。20包含文件file1.cppfile1.cppfont.hfont.hfile1.cppfile1.cpp#includefont.h A B B A21谢谢观赏

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号