C语言指针结构与联合_第1页
C语言指针结构与联合_第2页
C语言指针结构与联合_第3页
C语言指针结构与联合_第4页
C语言指针结构与联合_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C语言基础教程:指针、结构、联合和枚举本节专门对第二节曾讲述过的指针作一详述。并介绍Turbo C新的数据类型: 结构、联合和枚举, 其中结构和联合是以前讲过的五种基本数据类型(整型、浮 点型、字符型、指针型和无值型)的组合。 枚举是一个被命名为整型常数的集合。 最后对类型说明(typedef)和预处理指令作一阐述。1、 指         针(point)    学习Turbo C语言, 如果你不能用指针编写有效、正确和灵活的程序,  可以&#

2、160;认为你没有学好C语言。指针、地址、数组及其相互关系是C语言中最有特色的部 分。规范地使用指针, 可以使程序达到简单明了, 因此, 我们不但要学会如何正 确地使用指针, 而且要学会在各种情况下正确地使用指针变量。     1. 指针和地址     1.1 指针基本概念及其指针变量的定义     1.1.1 指针变量的定义     我们知道变量在计算机内是占有一块存贮区域的, 变量的值就存放在这块区 域

3、之中, 在计算机内部, 通过访问或修改这块区域的内容来访问或修改相应的变 量。Turbo C语言中, 对于变量的访问形式之一, 就是先求出变量的地址,  然后 再通过地址对它进行访问, 这就是这里所要论述的指针及其指针变量。     所谓变量的指针, 实际上指变量的地址。变量的地址虽然在形式上好象类似 于整数, 但在概念上不同于以前介绍过的整数, 它属于一种新的数据类型, 即指 针类型。Turbo C中, 一般用"指针"来指明这样一个表达式&x的类型,  而用 &qu

4、ot;地 址"作为它的值, 也就是说, 若x为一整型变量, 则表达式&x的类型是指向整数的 指针, 而它的值是变量x的地址。同样, 若      double d; 则&d的类型是指向以精度数d的指针, 而&d的值是双精度变量d的地址。所以, 指 针和地址是用来叙述一个对象的两个方面。虽然&x、&d的值分别是整型变量x 和 双精度变量d的地址, 但&x、&d的类型是不同的, 一个是指向整型变量x的指针, 而另一个则是指向

5、双精度变量d的指针。在习惯上,  很多情况下指针和地址这两 个术语混用了。     我们可以用下述方法来定义一个指针类型的变量。      int *ip; 首先说明了它是一指针类型的变量, 注意在定义中不要漏写符号"*",  否则它为 一般的整型变量了。另外, 在定义中的int 表示该指针变量为指向整型数的指针 类型的变量, 有时也可称ip为指向整数的指针。ip是一个变量, 它专门存放整型 变量的地址。 

6、    指针变量的一般定义为:      类型标识符  *标识符;     其中标识符是指针变量的名字, 标识符前加了"*"号,  表示该变量是指针变 量, 而最前面的"类型标识符"表示该指针变量所指向的变量的类型。一个指针变 量只能指向同一种类型的变量, 也就是讲, 我们不能定义一个指针变量, 既能指 向一整型变量又能指向双精度变量。     指

7、针变量在定义中允许带初始化项。如:       int i, *ip=&i; 注意, 这里是用&i对ip初始化, 而不是对*ip初始化。和一般变量一样,  对于外 部或静态指针变量在定义中若不带初始化项, 指针变量被初始化为NULL, 它的值 为0。Turbo C中规定, 当指针值为零时, 指针不指向任何有效数据, 有时也称指 针为空指针。因此, 当调用一个要返回指针的函数(第五节中介绍)时, 常使用返 回值为NULL来指示函数调用中某些错误情况的发生。1.1

8、.2 指针变量的引用     既然在指针变量中只能存放地址, 因此, 在使用中不要将一个整数赋给一指 针变量。下面的赋值是不合法的:      int *ip;      ip=100; 假设      int i=200, x;      int *ip; 我们定义了两个整型变量i, x, 还定义了一个指向整型数的指针变量ip

9、。i, x中 可存放整数, 而ip中只能存放整型变量的地址。我们可以把i的地址赋给ip:      ip=&i; 此时指针变量ip指向整型变量i, 假设变量i的地址为1800, 这个赋值可形象理解 为下图所示的联系。             ip            &

10、#160;  i                         1800 200                          

11、60;    图1. 给指针变量赋值 以后我们便可以通过指针变量ip间接访问变量i, 例如:      x=*ip; 运算符*访问以ip为地址的存贮区域, 而ip中存放的是变量i的地址, 因此, *ip 访问的是地址为1800的存贮区域(因为是整数, 实际上是从1800开始的两个字节), 它就是i所占用的存贮区域, 所以上面的赋值表达式等价于      x=i;     另外, 指针变量

12、和一般变量一样, 存放在它们之中的值是可以改变的, 也就 是说可以改变它们的指向, 假设      int i, j, *p1, *p2;      i='a'      j='b'      p1=&i;      p2=&j; 则建立如下图所示的联系:  &

13、#160;          p1               i                            

14、;   'a'                               p2               i   

15、60;                           'b'                          

16、60;     图2. 赋值运算结果 这时赋值表达式:      p2=p1 就使p2与p1指向同一对象i, 此时*p2就等价于i, 而不是j, 图2.就变成图3.所示:             p1              

17、i                               'a'                       

18、;   p2             j                                'b'        

19、;                       图3. p2=p1时的情形 如果执行如下表达式:      *p2=*p1; 则表示把p1指向的内容赋给p2所指的区域, 此时图2.就变成图4.所示           &

20、#160; p1               i                               'a'     

21、0;                         p2               j             &#

22、160;                 'a'                               图4. *p2=*p1时的情形   

23、;  通过指针访问它所指向的一个变量是以间接访问的形式进行的, 所以比直接 访问一个变量要费时间, 而且不直观, 因为通过指针要访问哪一个变量, 取决于 指针的值(即指向), 例如"*p2=*p1;"实际上就是"j=i;", 前者不仅速度慢而且目 的不明。但由于指针是变量, 我们可以通过改变它们的指向, 以间接访问不同的 变量, 这给程序员带来灵活性, 也使程序代码编写得更为简洁和有效。     指针变量可出现在表达式中, 设   &#

24、160;  int x, y *px=&x; 指针变量px指向整数x, 则*px可出现在x能出现的任何地方。例如:      y=*px+5;  /*表示把x的内容加5并赋给y*/      y=+*px;  /*px的内容加上1之后赋给y  +*px相当于+(px)*/      y=*px+;  /*相当于y=*px; px+*/ 1.2. 地址运算 &#

25、160;   指针允许的运算方式有:     (1). 指针在一定条件下, 可进行比较, 这里所说的一定条件,  是指两个指 针指向同一个对象才有意义, 例如两个指针变量p, q指向同一数组, 则<, >, >=, <=, =等关系运算符都能正常进行。若p=q为真, 则表示p, q指向数组的同一元 素; 若p<q为真, 则表示p所指向的数组元素在q所指向的数组元素之前(对于指向 数组元素的指针在下面将作详细讨论)。   

26、60; (2). 指针和整数可进行加、减运算。设p是指向某一数组元素的指针, 开始 时指向数组的第0号元素, 设n为一整数, 则      p+n 就表示指向数组的第n号元素(下标为n的元素)。     不论指针变量指向何种数据类型, 指针和整数进行加、减运算时, 编译程序 总根据所指对象的数据长度对n放大, 在一般微机上, char放大因子为1, int、 short放大因子为2, long和float放大因子为4, double放大因子为8。 对于下面 

27、;讲述到的结构或联合, 也仍然遵守这一原则。     (3). 两个指针变量在一定条件下, 可进行减法运算。设p, q指向同一数组, 则p-q的绝对值表示p所指对象与q所指对象之间的元素个数。 其相减的结果遵守 对象类型的字节长度进行缩小的规则。     2. 指针和数组     指针和数组有着密切的关系, 任何能由数组下标完成的操作也都可用指针来 实现, 但程序中使用指针可使代码更紧凑、更灵活。 2.1. 指向数组元素的指针 

28、;    我们定义一个整型数组和一个指向整型的指针变量:           int a10, *p; 和前面介绍过的方法相同, 可以使整型指针p指向数组中任何一个元素,  假定给 出赋值运算           p=&a0; 此时, p指向数组中的第0号元素, 即a0, 指针变量p中包含了数组元素a0 的 地

29、址, 由于数组元素在内存中是连续存放的, 因此,  我们就可以通过指针变量p 及其有关运算间接访问数组中的任何一个元素。     Turbo C中, 数组名是数组的第0号元素的地址, 因此下面两个语句是等价的      p=&a0;      p=a; 根据地址运算规则, a+1为a1的地址, a+i就为ai的地址。     下面我们用指针给出数组元素的地址和内容的几种表示形式。

30、     (1). p+i和a+i均表示ai的地址, 或者讲, 它们均指向数组第i号元素, 即 指向ai。     (2). *(p+i)和*(a+i)都表示p+i和a+i所指对象的内容, 即为ai。     (3). 指向数组元素的指针, 也可以表示成数组的形式, 也就是说,  它允许 指针变量带下标, 如pi与*(p+i)等价。     假若:     

31、 p=a+5; 则p2就相当于*(p+2), 由于p指向a5, 所以p2就相当于a7。而p-3就相 当于*(p-3), 它表示a2。2.2. 指向二维数组的指针     2.2.1. 二维数组元素的地址     为了说明问题, 我们定义以下二维数组:      int a34=0,1,2,3, 4,5,6,7, 8,9,10,11; a为二维数组名, 此数组有3行4列, 共12个元素。但也可这样来理解, 数组a由三 个元素组成

32、: a0, a1, a2。而它匀中每个元素又是一个一维数组, 且都含 有4个元素 (相当于4列),  例如, a0所代表的一维数组所包含的 4 个元素为 a00, a01, a02, a03。如图5.所示:                a   a0  0 1 2 3               &

33、#160;         a1  4 5 6 7                         a2  8 9 1011                 &

34、#160;                图5.     但从二维数组的角度来看, a代表二维数组的首地址,  当然也可看成是二维 数组第0行的首地址。a+1就代表第1行的首地址, a+2就代表第2行的首地址。如 果此二维数组的首地址为1000, 由于第0行有4个整型元素, 所以a+1为1008, a+2 也就为1016。如图6.所示   

35、;                          a34                    a     

36、0;             (1000)0 1 2 3                     a+1                 (

37、1008)4 5 6 7                     a+2                 (1016)8 9 1011          

38、60;                                             图6.     既然我们把a0,

39、a1, a2看成是一维数组名, 可以认为它们分别代表它 们所对应的数组的首地址, 也就是讲,  a0代表第 0 行中第 0 列元素的地址, 即&a00, a1是第1行中第0列元素的地址, 即&a10, 根据地址运算规则, a0+1即代表第0行第1列元素的地址, 即&a01, 一般而言, ai+j即代表第 i行第j列元素的地址, 即&aij。     另外, 在二维数组中, 我们还可用指针的形式来表示各元素的地址。如前所 述, a0与*(a+0)等价, a1与*(a

40、+1)等价, 因此ai+j就与*(a+i)+j等价, 它 表示数组元素aij的地址。     因此, 二维数组元素aij可表示成*(ai+j)或*(*(a+i)+j),  它们都与 aij等价, 或者还可写成(*(a+i)j。     另外, 要补充说明一下, 如果你编写一个程序输出打印a和*a,  你可发现它 们的值是相同的, 这是为什么呢? 我们可这样来理解: 首先, 为了说明问题, 我 们把二维数组人为地看成由三个数组元素a0, a1, a2组成,

41、将a0, a1, a2看成是数组名它们又分别是由4个元素组成的一维数组。因此, a表示数组第 0行的地址, 而*a即为a0, 它是数组名, 当然还是地址, 它就是数组第0 行第0 列元素的地址。2.2.2 指向一个由n个元素所组成的数组指针     在Turbo C中, 可定义如下的指针变量:       int (*p)3;     指针p为指向一个由3个元素所组成的整型数组指针。在定义中, 圆括号是不 能少的,

42、否则它是指针数组, 这将在后面介绍。这种数组的指针不同于前面介绍 的整型指针, 当整型指针指向一个整型数组的元素时, 进行指针(地址)加1运算, 表示指向数组的下一个元素, 此时地址值增加了2(因为放大因子为2), 而如上所 定义的指向一个由3个元素组成的数组指针, 进行地址加1运算时, 其地址值增加 了6(放大因子为2x3=6), 这种数组指针在Turbo C中用得较少,  但在处理二维数 组时, 还是很方便的。例如:         

43、0; int a34, (*p)4;           p=a;     开始时p指向二维数组第0行, 当进行p+1运算时, 根据地址运算规则,  此时 放大因子为4x2=8, 所以此时正好指向二维数组的第1行。和二维数组元素地址计 算的规则一样, *p+1指向a01, *(p+i)+j则指向数组元素aij。      例1    &#

44、160; int a3 4=      1,3,5,7,      9,11,13,15,      17,19,21,23     ;     main()               int i,(*b)4;  &#

45、160;         b=a+1;                  /* b指向二维数组的第1行, 此时*b0或                   &#

46、160;                  *b是a10 */          for(i=1;i<=4;b=b0+2,i+)/* 修改b的指向, 每次增加2 */            printf("%dt&

47、quot;,*b0);          printf("n");          for (i=0; i<2; i+)             b=a+i;          &#

48、160;       /* 修改b的指向,  每次跳过二维数组的                                       一行 *

49、/            printf("%dt",*(bi+1);                   printf ("n");           程序运行结果如下: 

50、60;    9    13   17   21      3    11   193. 字符指针     我们已经知道, 字符串常量是由双引号括起来的字符序列, 例如:           "a string" 就是一个字符串常

51、量, 该字符串中因为字符a后面还有一个空格字符, 所以它由8 个字符序列组成。在程序中如出现字符串常量C 编译程序就给字符串常量按排一 存贮区域, 这个区域是静态的, 在整个程序运行的过程中始终占用, 平时所讲的 字符串常量的长度是指该字符串的字符个数, 但在按排存贮区域时, C 编译程序 还自动给该字符串序列的末尾加上一个空字符'0', 用来标志字符串的结束, 因 此一个字符串常量所占的存贮区域的字节数总比它的字符个数多一个字节。     Turbo C中操作一个字符串常量的方法有:&#

52、160;    (1). 把字符串常量存放在一个字符数组之中, 例如:           char s="a string" 数组s共有9个元素所组成, 其中s8中的内容是'0'。实际上, 在字符数组定义 的过程中, 编译程序直接把字符串复写到数组中, 即对数组s初始化。     (2). 用字符指针指向字符串, 然后通过字符指针来访问字符串存贮区域。 当字符

53、串常量在表达式中出现时, 根据数组的类型转换规则, 它被转换成字符指 针。因此, 若我们定义了一字符指针cp:      char *cp; 于是可用:      cp="a string" 使cp指向字符串常量中的第0号字符a, 如图7.所示。             cp    

54、60;                      a   s t r i n g 0                             

55、;                图7. 以后我们可通过cp来访问这一存贮区域, 如*cp或cp0就是字符a,  而cpi或 *(cp+i)就相当于字符串的第i号字符, 但企图通过指针来修改字符串常量的行为 是没有意义的。4. 指针数组     因为指针是变量, 因此可设想用指向同一数据类型的指针来构成一个数组, 这就是指针数组。数组中的每个元素都是指针变量

56、, 根据数组的定义, 指针数组 中每个元素都为指向同一数据类型的指针。指针数组的定义格式为:      类型标识 *数组名整型常量表达式;     例如:        int *a10; 定义了一个指针数组, 数组中的每个元素都是指向整型量的指针, 该数组由10个 元素组成, 即a0, a1, a2, ., a9, 它们均为指针变量。a为该指针数 组名, 和数组一样, a是常量, 不能对它进行增

57、量运算。a为指针数组元素a0的 地址, a+i为ai的地址, *a就是a0, *(a+i)就是ai。     为什么要定义和使用指针数组呢? 主要是由于指针数组对处理字符串提供了 更大的方便和灵活, 使用二维数组对处理长度不等的正文效率低, 而指针数组由 于其中每个元素都为指针变量, 因此通过地址运算来操作正文行是十分方便的。     指针数组和一般数组一样, 允许指针数组在定义时初始化, 但由于指针数组 的每个元素是指针变量, 它只能存放地址, 所以对指向字符串的指针数组在

58、说明 赋初值时, 是把存放字符串的首地址赋给指针数组的对应元素, 例如下面是一个 书写函数month_name(n), 此函数返回一个指向包含第n月名字的字符指针( 关于 函数, 第6节将专门介绍)。     例2: 打印1月至12月的月名:      char *month_name(int n)                

59、; static char *name=                "Illegal month",                "January",        

60、0;       "February",                "March",                "April",   

61、0;            "May",                "June",                "July"

62、,                "August",                "September",            

63、0;   "October",                "November",                "December"       

64、    ;           return(n<1|n>12)?name0:namen);            main()                 int i;   

65、;        for(i=0; i<13; i+)                printf("%sn", month_name(i); 2、结构(struct)    结构是由基本数据类型构成的、并用一个标识符来命名的各种变量的组合。 结构中可以使用不同的数据类型。   &#

66、160; 1. 结构说明和结构变量定义     在Turbo C中, 结构也是一种数据类型, 可以使用结构变量, 因此,  象其它 类型的变量一样, 在使用结构变量时要先对其定义。     定义结构变量的一般格式为:      struct 结构名                 类型 

67、变量名;           类型  变量名;           .      结构变量;     结构名是结构的标识符不是变量名。     类型为第二节中所讲述的五种数据类型(整型、浮点型、字符型、指针型和 无值型)。  &#

68、160;  构成结构的每一个类型变量称为结构成员, 它象数组的元素一样, 但数组中 元素是以下标来访问的, 而结构是按变量名字来访问成员的。     下面举一个例子来说明怎样定义结构变量。      struct string                 char name8;     

69、;      int age;           char sex2;           char depart20;           float wage1, wage2, wage3, wage4, wage5;  &

70、#160;   person;     这个例子定义了一个结构名为string的结构变量person,   如果省略变量名 person, 则变成对结构的说明。用已说明的结构名也可定义结构变量。这样定义 时上例变成:      struct string                 char n

71、ame8;           int age;           char sex2;           char depart20;           float wage1, wage2,

72、 wage3, wage4, wage5;      ;      struct string person;     如果需要定义多个具有相同形式的结构变量时用这种方法比较方便, 它先作 结构说明, 再用结构名来定义变量。     例如:      struct string Tianyr, Liuqi, .;    

73、; 如果省略结构名, 则称之为无名结构, 这种情况常常出现在函数内部, 用这 种结构时前面的例子变成:      struct                 char name8;           int age;      

74、;     char sex2;           char depart20;           float wage1, wage2, wage3, wage4, wage5;      Tianyr, Liuqi;2. 结构变量的使用     结构是一个新的数

75、据类型, 因此结构变量也可以象其它类型的变量一样赋值、 运算, 不同的是结构变量以成员作为基本变量。     结构成员的表示方式为:           结构变量.成员名     如果将"结构变量.成员名"看成一个整体,  则这个整体的数据类型与结构中 该成员的数据类型相同, 这样就可象前面所讲的变量那样使用。     下面这个

76、例子定义了一个结构变量, 其中每个成员都从键盘接收数据, 然后 对结构中的浮点数求和, 并显示运算结果, 同时将数据以文本方式存入一个名为 wage.dat的磁盘文件中。请注意这个例子中不同结构成员的访问。     例3:      #include <stdio.h>      main()            

77、     struct                  /*定义一个结构变量*/                char name8;        

78、0;       int age;                char sex2;                char depart20;        

79、;        float wage1, wage2, wage3, wage4, wage5;           a;           FILE *fp;           float wage;  

80、;         char c='Y'           fp=fopen("wage.dat", "w");    /*创建一个文件只写*/           while(c='Y'|c='y'

81、)         /*判断是否继续循环*/                           printf("nName:");          

82、;      scanf("%s", );     /*输入姓名*/                printf("Age:");               

83、; scanf("%d", &a.wage);    /*输入年龄*/                printf("Sex:");                scanf("%d", a.sex);

84、                printf("Dept:");                scanf("%s", a.depart);          

85、      printf("Wage1:");                scanf("%f", &a.wage1);   /*输入工资*/                pri

86、ntf("Wage2:");                scanf("%f", &a.wage2);                printf("Wage3:");     &

87、#160;          scanf("%f", &a.wage3);                printf("Wage4:");              &#

88、160; scanf("%f", &a.wage4);                printf("Wage5:");                scanf("%f", &a.wage5);  &#

89、160;             wage=a.wage1+a.wage2+a.wage3+a.wage4+a.wage5;                printf("The sum of wage is %6.2fn", wage);/*显示结果*/    

90、60;           fprintf(fp, "%10s%4d%4s%30s%10.2fn",  /*结果写入文件*/                             a.na

91、me, a.age, a.sex, a.depart, wage);                while(1)                            

92、0;        printf("Continue?<Y/N>");                     c=getche();             

93、0;       if(c='Y'|c='y'|c='N'|c='n')                          break;       

94、60;                              fclose(fp);       3. 结构数组和结构指针     结构是一种新的数据类型, 同样可以有结构数组和结构指针。   &

95、#160; 一、结构数组     结构数组就是具有相同结构类型的变量集合。假如要定义一个班级40个同学 的姓名、性别、年龄和住址, 可以定义成一个结构数组。如下所示:      struct           char name8;           char sex2;  

96、         int age;           char addr40;      student40;     也可定义为:      struct string         

97、  char name8;           char sex2;           int age;           char addr40;      ;      struct

98、 string student40;     需要指出的是结构数组成员的访问是以数组元素为结构变量的, 其形式为:           结构数组元素.成员名     例如:              student30.age    

99、 实际上结构数组相当于一个二维构造, 第一维是结构数组元素, 每个元素是 一个结构变量, 第二维是结构成员。     注意:     结构数组的成员也可以是数组变量。     例如:      struct a                 int m35; 

100、;          float f;           char s20;      y4;     为了访问结构a中结构变量y2的这个变量, 可写成        y2.m14 二、结构指针     结构

101、指针是指向结构的指针。它由一个加在结构变量名前的"*" 操作符来定 义, 例如用前面已说明的结构定义一个结构指针如下:      struct string           char name8;           char sex2;      

102、60;    int age;           char addr40;      *student;     也可省略结构指针名只作结构说明, 然后再用下面的语句定义结构指针。       struct string *student;     使用结构指针对结构成员的访问

103、, 与结构变量对结构成员的访问在表达方式 上有所不同。结构指针对结构成员的访问表示为:        结构指针名->结构成员     其中"->"是两个符号"-"和">"的组合, 好象一个箭头指向结构成员。例如要 给上面定义的结构中name和age赋值, 可以用下面语句:      strcpy(student->name, &quo

104、t;Lu G.C");      student->age=18;     实际上, student->name就是(*student).name的缩写形式。     需要指出的是结构指针是指向结构的一个指针, 即结构中第一个成员的首地 址, 因此在使用之前应该对结构指针初始化, 即分配整个结构长度的字节空间, 这可用下面函数完成, 仍以上例来说明如下:      stude

105、nt=(struct string*)malloc(size of (struct string);     size of (struct string)自动求取string结构的字节长度, malloc() 函数 定义了一个大小为结构长度的内存区域, 然后将其诈地址作为结构指针返回。     注意:     1. 结构作为一种数据类型,  因此定义的结构变量或结构指针变量同样有局 部变量和全程变量, 视定义的位置而定。  

106、   2. 结构变量名不是指向该结构的地址, 这与数组名的含义不同,  因此若需 要求结构中第一个成员的首地址应该是&结构变量名。     4. 结构的复杂形式 一、嵌套结构     嵌套结构是指在一个结构成员中可以包括其它一个结构, Turbo C 允许这种 嵌套。     例如: 下面是一个有嵌套的结构      struct string &#

107、160;         char name8;           int age;           struct addr address;      student;     其中: addr为另一个结构的结构名, 必须

108、要先进行, 说明, 即      struct addr           char city20;           unsigned lon zipcode;           char tel14;   &#

109、160;       如果要给student结构中成员address结构中的zipcode赋值, 则可写成:       student.address.zipcode=200001;     每个结构成员名从最外层直到最内层逐个被列出, 即嵌套式结构成员的表达 方式是:       结构变量名.嵌套结构变量名.结构成员名     其中:

110、 嵌套结构可以有很多, 结构成员名为最内层结构中不是结构的成员名。二、位结构     位结构是一种特殊的结构, 在需按位访问一个字节或字的多个位时, 位结构 比按位运算符更加方便。     位结构定义的一般形式为:      struct位结构名           数据类型 变量名: 整型常数;     &

111、#160;     数据类型 变量名: 整型常数;      位结构变量;     其中: 数据类型必须是int(unsigned或signed)。 整型常数必须是非负的整 数, 范围是015, 表示二进制位的个数, 即表示有多少位。     变量名是选择项, 可以不命名, 这样规定是为了排列需要。     例如: 下面定义了一个位结构。   &#

112、160;  struct           unsigned incon: 8;  /*incon占用低字节的07共8位*/           unsigned txcolor: 4;/*txcolor占用高字节的03位共4位*/           unsigned bgc

113、olor: 3;/*bgcolor占用高字节的46位共3位*/           unsigned blink: 1;  /*blink占用高字节的第7位*/      ch;     位结构成员的访问与结构成员的访问相同。     例如: 访问上例位结构中的bgcolor成员可写成:      

114、 ch.bgcolor       注意:     1. 位结构中的成员可以定义为unsigned, 也可定义为signed,  但当成员长 度为1时, 会被认为是unsigned类型。因为单个位不可能具有符号。     2. 位结构中的成员不能使用数组和指针, 但位结构变量可以是数组和指针, 如果是指针, 其成员访问方式同结构指针。     3. 位结构总长度(位数), 是各个位成员定

115、义的位数之和,  可以超过两个字 节。     4. 位结构成员可以与其它结构成员一起使用。     例如:      struct info           char name8;           int age;  &

116、#160;        struct addr address;           float pay;           unsigned state: 1;           unsigned pay: 1; 

117、;          workers;'     上例的结构定义了关于一个工从的信息。其中有两个位结构成员, 每个位结 构成员只有一位, 因此只占一个字节但保存了两个信息, 该字节中第一位表示工 人的状态, 第二位表示工资是否已发放。由此可见使用位结构可以节省存贮空间。联合(union)    1. 联合说明和联合变量定义     联合也是一种新的数据类型, 它是一种特

118、殊形式的变量。     联合说明和联合变量定义与结构十分相似。其形式为:      union 联合名           数据类型 成员名;           数据类型 成员名;           .&#

119、160;     联合变量名;     联合表示几个变量公用一个内存位置, 在不同的时间保存不同的数据类型 和不同长度的变量。     下例表示说明一个联合a_bc:      union a_bc           int i;       &#

120、160;   char mm;      ;     再用已说明的联合可定义联合变量。     例如用上面说明的联合定义一个名为lgc的联合变量, 可写成:       union a_bc lgc;     在联合变量lgc中, 整型量i和字符mm公用同一内存位置。     当一个联合被说明时, 编译程序自

121、动地产生一个变量, 其长度为联合中最大 的变量长度。     联合访问其成员的方法与结构相同。同样联合变量也可以定义成数组或指针, 但定义为指针时, 也要用"->"符号, 此时联合访问成员可表示成:      联合名->成员名     另外, 联合既可以出现在结构内, 它的成员也可以是结构。     例如:      stru

122、ct           int age;           char *addr;           union               

123、int i;                char *ch;           x;      y10;     若要访问结构变量y1中联合x的成员i, 可以写成:       y1.x.i;     若要访问结构变量y2中联合x的字符串指针ch的第一个字符可写成:       *y2.x.ch;     若写成"y2.x.*ch;"是错误的。 2. 结构和联合的区别     结构和联合有下列区别:   &#

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论