Discuz教程网

C语言案例教程 - 第八章 复合数据类型

[复制链接]
authicon 09927306 发表于 2011-1-8 18:07:44 | 显示全部楼层 |阅读模式
本帖最后由 09927306 于 2011-1-8 18:23 编辑

第8章:复合数据类型
【例8-1】
结构变量的初始化。


  1.         #include<stdio.h>
  2.         struct st
  3.           { char str[5];
  4.             char *s;
  5.             int a;
  6.             struct
  7.               { char c;
  8.                 float w;
  9.               }d;
  10.            };
  11.         main()
  12.           { struct st x={"101","abcd",28, \'n\',45.8};
  13.             printf("%4s %-9s %3d %c %.2f\\n",x.str,x.s,x.a,x.d.c,x.d.w);
  14.           }
复制代码


程序运行结果如下:

101 abcd
28 n 45.80
【例8-2】
结构数组的初始化。


  1.       #include<stdio.h>
  2.         struct st
  3.           { char str[5];
  4.             char *s;
  5.             int a;
  6.             struct
  7.               { char c;
  8.                 float w;
  9.               }d;
  10.            }
  11.         main()
  12.           { struct st x[2]={{"101","abcd",28, \'n\',45.8},
  13.                             {"1001","dog&god",14, \'y\',123}};
  14.             int i;
  15.             for(i=0;i<2;i++)
  16.               printf("%4s %-9s %3d %c %.2f\\n",
  17.                          x[i].str,x[i].s,x[i].a,x[i].d.c,x[i].d.w);
  18.           }
复制代码


程序运行结果如下:

101 abcd
28 n 45.80

1001 dog&god
14 y 123.00
【例8-3】
假设学生的3门课成绩已保存在一个结构数组中,要求用子程序计算并返回3门课的总分。
先定义一个外部型的结构类型,在主程序main()中创建结构数组,并将该数组的成员score(数组)传递到子程序add()中,由add()计算总分并返回。


  1. #include <stdio.h>
  2.         struct stu
  3.           { char *name; int score[3]; int total;};
  4.         main()
  5.           { struct stu student[30];
  6.             int i;
  7.             for (i=0;i<30;i++)                 /*创建结构数组*/
  8.               { scanf("%s",student[i].name);
  9.                 scanf("%d%d%d",&student[i].score[0],
  10.                        &student[i].score[1],&student[i].score[2]);
  11.                 student[i].total=add(student[i].score[0],
  12.                        student[i].score[1],student[i].score[2]);  /*调用add*/
  13.               }
  14.             for(i=0;i<30;i++)
  15.               printf("%-9s %d %d %d %d\\n",student[i].name,
  16.                        student[i].score[0],student[i].score[1],
  17.                        student[i].score[2],student[i].total);
  18.           }
  19.         add(int x,int y,int z)                                 /*计算并返回总分*/
  20.           { return x+y+z;}
复制代码


【例8-4】
定义一个结构变量,其成员包括两个整数a和b及一个字符串ch。主程序将该结构数据传递给子程序f1(),子程序计算a+b并保存在a中,同时将字符串ch中第3个字符替换为\'x\',最后输出处理结果。


  1. #include <stdio.h>
  2.         struct sample
  3.           { int a,b; char *ch;};
  4.         void f1(struct sample parm)
  5.           { parm.a+=parm.b;
  6.             parm.ch[2]=\'x\';
  7.             printf("%d,%s\\n",parm.a,parm.ch);
  8.           }
  9.         main(void)
  10.           { struct sample arg;
  11.             arg.a=1000;arg.b=100;arg.ch="abcd";
  12.             f1(arg);
  13.             printf("%d,%s\\n",arg.a,arg.ch);
  14.           }
复制代码


【例8-5】
将例8-4改用结构指针来传递结构型数据。


  1. #include <stdio.h>
  2.         struct sample
  3.           { int a,b; char *ch;};
  4.         void f1(struct sample *p)
  5.           { p->a+=p->b;
  6.             p->ch[2]=\'x\';
  7.             printf("%d,%s\\n",p->a,p->ch);
  8.           }
  9.         main()
  10.           { struct sample arg;
  11.             arg.a=1000;arg.b=100;arg.ch="abcd";
  12.             f1(&arg);
  13.             printf("%d,%s\\n",arg.a,arg.ch);
  14.           }
复制代码


【例8-6】
建立一个小通讯录:input()用于输入通讯录数据,display()用于输出通讯录,主程序通过结构数组名调用input()和display()。


  1. #include <stdio.h>
  2.     #define MAX 10
  3.     struct telephone
  4.       { char name[20]; char mobile[12]; char phone[12];};
  5.     input(struct telephone *p)
  6.       { int i;
  7.         for (i=0;i<MAX;i++)
  8.           { printf("Name?");
  9.             gets(p->name);
  10.             if (p->name[0]==\'\\0\') return(i);  /*提前结束输入*/
  11.             printf("Mobile?");
  12.             scanf("%*c%s",p->mobile);
  13.             printf("Telephone?");
  14.             scanf("%*c%s%*c",p->phone);
  15.           };
  16.         return MAX;
  17.       }
  18.     void display(struct telephone *p,int n)
  19.       { int i;
  20.         for (i=0;i<n;i++,p++)
  21.           printf("%-20s %-12s %-12s\\n",p->name,p->mobile,p->phone);
  22.       }
  23.     main()
  24.       { struct telephone tx[MAX];
  25.         int n;
  26.         n=input(tx);
  27.         display(tx,n);             /*输出通讯录*/
  28.       }
复制代码


【例8-7】
一个汽车档案中包括汽车的编号、颜色和型号。输入一个汽车编号,由find()函数进行查找,根据查找结果输出查找到汽车的信息。


  1. #include <stdio.h>
  2.         struct sample
  3.           { int num; char color;
  4.             char type;} car[]={101,\'G\',\'c\',210,\'Y\',\'m\',105,\'R\',\'l\',
  5.                                    220,\'B\',\'s\',308,\'W\',\'b\',0,\'\\0\',\'\\0\'};

  6.         struct sample find(int n)
  7.           { int i;
  8.             for (i=0;car[i].num!=0;i++)
  9.               if (car[i].num==n) break;
  10.                  return(car[i]);
  11.           }

  12.         main()
  13.           { int number;
  14.             struct sample result;
  15.             printf("Enter the number:");
  16.             scanf("%d",&number);
  17.             result=find(number);
  18.             if (result.num!=0)
  19.               {  printf("number:%d  ",result.num);
  20.                  printf("Color:%c  ",result.color);
  21.                  printf("type:%c\\n",result.type);
  22.               }
  23.             else
  24.                printf("Not found\\n");
  25.           }
复制代码


上一章:C语言案例教程 - 第七章 程序的模块结构和C函数
下一章:C语言案例教程 - 第九章 文件




上一篇:C语言案例教程 - 第七章 程序的模块结构和C函数
下一篇:C语言案例教程 - 第九章 文件
authicon  楼主| 09927306 发表于 2011-1-8 18:08:35 | 显示全部楼层
本帖最后由 09927306 于 2011-1-8 18:24 编辑

【例8-8】
例8-7的程序中的结构型函数也可以改用结构指针型函数。程序如下:


  1. #include <stdio.h>
  2.         struct sample
  3.           { int num; char color;
  4.             char type;} car[]={101,'G','c',210,'Y','m',105,'R','l',
  5.                                    220,'B','s',308,'W','b',0,'\0','\0'};

  6.         struct sample *find(int n)
  7.           { int i;
  8.             for (i=0;car[i].num!=0;i++)
  9.               if (car[i].num==n) break;
  10.                  return(&car[i]);
  11.           }

  12.         main()
  13.           { int number;
  14.             struct sample *result;
  15.             printf("Enter the number:");
  16.             scanf("%d",&number);
  17.             result=find(number);
  18.             if (result->num!=0)
  19.               {  printf("number:%d  ",result->num);
  20.                  printf("Color:%c  ",result->color);
  21.                  printf("type:%c\n",result->type);
  22.               }
  23.             else
  24.                printf("Not found\n");
  25.           }
复制代码



【例8-9】
单向循环链表是链头和链尾相接的一种链表,如图8-5所示。编一个程序创建具有5个节点的单向循环链表,并计算该链表中每3个相邻节点数据域中数值的和,从中找出最小值。
图8-5
单向循环链表示意图


  1. #include <stdlib.h>
  2.         struct node
  3.           { int data;
  4.             struct node *next;};
  5.         main()
  6.           { struct node *h,*p,*q;
  7.             int i,m,m3;
  8.         /* 建立5个节点的单向循环链表 */
  9.             p=q=h=(struct node *)malloc(sizeof(struct node));
  10.             for (i=0;i<5;i++)
  11.               { printf("Input data:");
  12.                 scanf("%d",&p->data);          /* 建立当前节点数据域 */
  13.                 p=(struct node *)malloc(sizeof(struct node));
  14.                 if (i==4) continue;
  15.                 q->next=p;                     /* 保存下一节点首地址 */
  16.                 q=p;
  17.               }
  18.         /* 链头和链尾相接,形成单向循环链表 */
  19.                 q->next=h;
  20.         /* p指向链头 */
  21.                 p=h;
  22.         /* 计算每3个相邻节点数据值之和,寻找最小值,直至回到链头 */
  23.                 m3=p->data+p->next->data+p->next->next->data;
  24.                 printf("%d\t",m3);             /*输出前3个节点数据之和*/
  25.                 for (p=p->next;p!=h;p=p->next)
  26.                   { m=p->data+p->next->data+p->next->next->data;
  27.                     printf("%d\t",m);              /*输出相邻3个节点数据之和*/
  28.                     if (m3>m) m3=m;
  29.                   }
  30.                 printf("MIN=%d\n",m3);         /*输出最小值*/
  31.           }
复制代码



【例8-10】
利用联合自动选择输入输出格式控制的程序。
我们可以定义一个结构sdata,它的一个成员是联合udata,用来存放各种类型的变量样本;另一个成员是整型变量type,用来存放值的类型(如int型为1,long int型为2,float型为3等),程序接收到用户输入类型代码后,可以自动确定用哪一种格式转换说明符来正确输入和输出数据。


  1. #include <stdio.h>
  2.         #define INT 1
  3.         #define LONG 2
  4.         #define FLOAT 3
  5.         #define DOUBLE 4
  6.         #define CHAR 5
  7.         #define STRING 6
  8.         union uda
  9.           { int uin; long ulo; float ufl;
  10.             double udo; char uch; char *ust;}udata;
  11.         struct sda
  12.           { union uda udata; int type;};
  13.         void in_out();
  14.         main()
  15.           { struct sda sdata,*p=&sdata;
  16.             printf("Input type:");
  17.             scanf("%d%*c",&p->type);
  18.             in_out(p);
  19.           }
  20.         void in_out(struct sda *b)
  21.           { printf("Input value:");
  22.             switch(b->type)
  23.               { case INT:
  24.                   scanf("%d",&b->udata.uin);
  25.                   printf("%d\n",b->udata.uin); break;
  26.                 case LONG:
  27.                   scanf("%ld",&b->udata.ulo);
  28.                   printf("%ld\n",b->udata.ulo); break;
  29.                 case FLOAT:
  30.                   scanf("%f",&b->udata.ufl);
  31.                   printf("%f\n",b->udata.ufl); break;
  32.                  case DOUBLE:
  33.                   scanf("%f",&b->udata.udo);
  34.                   printf("%lf\n",b->udata.udo); break;
  35.                 case CHAR:
  36.                   scanf("%c",&b->udata.uch);
  37.                   printf("%c\n",b->udata.uch); break;
  38.                 case STRING:
  39.                   printf("%s",b->udata.ust);
  40.                   printf("%s\n",b->udata.ust); break;
  41.                 default:
  42.                   printf("Type error");
  43.               }
  44.           }
复制代码



【例8-11】
利用联合成员共享存储单元的特点,将int型数据的高字节和低字节分离出来。
在IBM PC系列计算机中,int型数据的存储格式是低字节在前,高字节在后。例如,整数6699的十六进制表示为0x1a2b,其存储格式为:
2b

1a

因此,可以用字符型数组ch[2]与int型变量a共享存储单元。这样,c[0]和c[1]分别与a的高字节和低字节共享存储单元,通过ch[0]和ch[1]即可分离出a的2个字节。程序如下:


  1. union un
  2.           { int a;
  3.             char ch[2]; }data;
  4.         main()
  5.           { scanf("%x",&data.a);
  6.             printf("%x  %x\n",data.ch[0],data.ch[1]);
  7.           }
复制代码


程序运行时,若输入为:1a2b,则输出为:2b
1a。
【例8-12】
位段成员的初始化、赋值和输出。


  1. main()
  2.       { struct bit
  3.          { unsigned a:1;
  4.            unsigned b:2;
  5.            unsigned c:3;
  6.            int d; } s={1,2,3,4};
  7.         s.c=7;s.d=125;
  8.         printf("%d  %d  %d  %d\n",s.a,s.b,s.c,s.d);
  9.       }
复制代码


程序运行结果如下:
1
2
5
125
【例8-13】
位段的输入和输出。
由于位段没有自己的地址,不能直接用scanf()来输入。解决这一问题的一种方法是先将数据输入到一个无符号整型变量中,再通过强制类型转换把该变量的地址赋给位段结构变量的指针,使输入的整数被自动赋给位段结构的各个成员。


  1. struct bit
  2.       { unsigned bund_bit:2;
  3.         unsigned char_bit:2;
  4.         unsigned pari_bit:1;
  5.         unsigned even_bit:2;
  6.         unsigned stop_bit:2;
  7.         unsigned dummy_bit:8; };
  8.     main()
  9.       { struct bit *p;
  10.         unsigned int word;
  11.         printf("Input the value of word(HEX): ");
  12.         scanf("%x",&word);
  13.         p=(struct bit *)&word;
  14.         printf("%d  %d  %d  %d  %d\n",p->bund_bit,p->char_bit,
  15.                            p->pari_bit,p->even_bit,p->stop_bit);
  16.       }
复制代码


程序在IBM PC系列计算机上的运行结果如下:

Input the value of word (HEX):b6↙

2
1
1
1
1
【例8-14】
也可以利用联合成员共享存储单元的特点,将一个整型值装入位段。



  1. struct bit
  2.       { unsigned bund_bit:2;
  3.         unsigned char_bit:2;
  4.         unsigned pari_bit:1;
  5.         unsigned even_bit:2;
  6.         unsigned stop_bit:2;
  7.         unsigned dummy_bit:8; };
  8.     main()
  9.       { union
  10.          { struct bit eq; unsigned i; } abc;
  11.         abc.i=182;
  12.         printf("%d  %d  %d  %d  %d\n",abc.eq.bund_bit,abc.eq.char_bit,
  13. abc.eq.pari_bit,abc.eq.even_bit,abc.eq.stop_bit);
  14.      }
复制代码




【例8-15】

枚举变量用做循环变量和数组下标。


  1. enum coin {penny,nickel,dime,quarter,half_dollar,dollar};
  2.     char name[][10]={"January","February","March","April","May","June",
  3.           "July","August","September","October","November","December"};
  4.     main()
  5.       { enum coin money;
  6.         for(money=penny;money<=dollar;money++)
  7.           printf("%s  ",name[money]);
  8.       }
复制代码

程序运行结果如下:

January
February
March
April
May
June
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-2 21:55

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表