| 本帖最后由 09927306 于 2011-1-8 18:24 编辑 
 
 【例8-8】 例8-7的程序中的结构型函数也可以改用结构指针型函数。程序如下: 
 复制代码
#include <stdio.h>
        struct sample
          { int num; char color;
            char type;} car[]={101,'G','c',210,'Y','m',105,'R','l',
                                   220,'B','s',308,'W','b',0,'\0','\0'};
        struct sample *find(int n)
          { int i;
            for (i=0;car[i].num!=0;i++)
              if (car[i].num==n) break;
                 return(&car[i]);
          }
        main()
          { int number;
            struct sample *result;
            printf("Enter the number:");
            scanf("%d",&number);
            result=find(number);
            if (result->num!=0)
              {  printf("number:%d  ",result->num);
                 printf("Color:%c  ",result->color);
                 printf("type:%c\n",result->type);
              }
            else
               printf("Not found\n");
          }
 
 
 【例8-9】 单向循环链表是链头和链尾相接的一种链表,如图8-5所示。编一个程序创建具有5个节点的单向循环链表,并计算该链表中每3个相邻节点数据域中数值的和,从中找出最小值。 图8-5 单向循环链表示意图
 
 复制代码
#include <stdlib.h>
        struct node
          { int data;
            struct node *next;};
        main()
          { struct node *h,*p,*q;
            int i,m,m3;
        /* 建立5个节点的单向循环链表 */
            p=q=h=(struct node *)malloc(sizeof(struct node));
            for (i=0;i<5;i++)
              { printf("Input data:");
                scanf("%d",&p->data);          /* 建立当前节点数据域 */
                p=(struct node *)malloc(sizeof(struct node));
                if (i==4) continue;
                q->next=p;                     /* 保存下一节点首地址 */
                q=p;
              }
        /* 链头和链尾相接,形成单向循环链表 */
                q->next=h;
        /* p指向链头 */
                p=h;
        /* 计算每3个相邻节点数据值之和,寻找最小值,直至回到链头 */
                m3=p->data+p->next->data+p->next->next->data;
                printf("%d\t",m3);             /*输出前3个节点数据之和*/
                for (p=p->next;p!=h;p=p->next)
                  { m=p->data+p->next->data+p->next->next->data;
                    printf("%d\t",m);              /*输出相邻3个节点数据之和*/
                    if (m3>m) m3=m;
                  }
                printf("MIN=%d\n",m3);         /*输出最小值*/
          }
 
 
 【例8-10】 利用联合自动选择输入输出格式控制的程序。 我们可以定义一个结构sdata,它的一个成员是联合udata,用来存放各种类型的变量样本;另一个成员是整型变量type,用来存放值的类型(如int型为1,long int型为2,float型为3等),程序接收到用户输入类型代码后,可以自动确定用哪一种格式转换说明符来正确输入和输出数据。 
 复制代码
#include <stdio.h>
        #define INT 1
        #define LONG 2
        #define FLOAT 3
        #define DOUBLE 4
        #define CHAR 5
        #define STRING 6
        union uda
          { int uin; long ulo; float ufl;
            double udo; char uch; char *ust;}udata;
        struct sda
          { union uda udata; int type;};
        void in_out();
        main()
          { struct sda sdata,*p=&sdata;
            printf("Input type:");
            scanf("%d%*c",&p->type);
            in_out(p);
          }
        void in_out(struct sda *b)
          { printf("Input value:");
            switch(b->type)
              { case INT:
                  scanf("%d",&b->udata.uin); 
                  printf("%d\n",b->udata.uin); break;
                case LONG:
                  scanf("%ld",&b->udata.ulo); 
                  printf("%ld\n",b->udata.ulo); break;
                case FLOAT:
                  scanf("%f",&b->udata.ufl); 
                  printf("%f\n",b->udata.ufl); break;
                 case DOUBLE:
                  scanf("%f",&b->udata.udo); 
                  printf("%lf\n",b->udata.udo); break;
                case CHAR:
                  scanf("%c",&b->udata.uch); 
                  printf("%c\n",b->udata.uch); break;
                case STRING:
                  printf("%s",b->udata.ust); 
                  printf("%s\n",b->udata.ust); break; 
                default:
                  printf("Type error");
              }
          }
 
 
 【例8-11】 利用联合成员共享存储单元的特点,将int型数据的高字节和低字节分离出来。 在IBM PC系列计算机中,int型数据的存储格式是低字节在前,高字节在后。例如,整数6699的十六进制表示为0x1a2b,其存储格式为: 因此,可以用字符型数组ch[2]与int型变量a共享存储单元。这样,c[0]和c[1]分别与a的高字节和低字节共享存储单元,通过ch[0]和ch[1]即可分离出a的2个字节。程序如下: 
 复制代码
union un
          { int a;
            char ch[2]; }data;
        main()
          { scanf("%x",&data.a);
            printf("%x  %x\n",data.ch[0],data.ch[1]);
          }
 
 程序运行时,若输入为:1a2b,则输出为:2b1a。
 【例8-12】 位段成员的初始化、赋值和输出。 
 复制代码
main()
      { struct bit
         { unsigned a:1;
           unsigned b:2;
           unsigned c:3;
           int d; } s={1,2,3,4};
        s.c=7;s.d=125;
        printf("%d  %d  %d  %d\n",s.a,s.b,s.c,s.d);
      }
 
 程序运行结果如下: 12
 5
 125
 【例8-13】 位段的输入和输出。 由于位段没有自己的地址,不能直接用scanf()来输入。解决这一问题的一种方法是先将数据输入到一个无符号整型变量中,再通过强制类型转换把该变量的地址赋给位段结构变量的指针,使输入的整数被自动赋给位段结构的各个成员。 
 复制代码
struct bit
      { unsigned bund_bit:2;
        unsigned char_bit:2; 
        unsigned pari_bit:1; 
        unsigned even_bit:2; 
        unsigned stop_bit:2;
        unsigned dummy_bit:8; };
    main()
      { struct bit *p;
        unsigned int word;
        printf("Input the value of word(HEX): ");
        scanf("%x",&word);
        p=(struct bit *)&word;
        printf("%d  %d  %d  %d  %d\n",p->bund_bit,p->char_bit,
                           p->pari_bit,p->even_bit,p->stop_bit);
      }
 
 程序在IBM PC系列计算机上的运行结果如下: Input the value of word (HEX):b6↙
 2
 1
 1
 1
 1
 【例8-14】 也可以利用联合成员共享存储单元的特点,将一个整型值装入位段。 
 
 复制代码
struct bit
      { unsigned bund_bit:2;
        unsigned char_bit:2; 
        unsigned pari_bit:1; 
        unsigned even_bit:2; 
        unsigned stop_bit:2;
        unsigned dummy_bit:8; };
    main()
      { union
         { struct bit eq; unsigned i; } abc;
        abc.i=182;
        printf("%d  %d  %d  %d  %d\n",abc.eq.bund_bit,abc.eq.char_bit,
abc.eq.pari_bit,abc.eq.even_bit,abc.eq.stop_bit);
     }
 
 
 
 【例8-15】 
 枚举变量用做循环变量和数组下标。 
 复制代码
enum coin {penny,nickel,dime,quarter,half_dollar,dollar};
    char name[][10]={"January","February","March","April","May","June",
          "July","August","September","October","November","December"};
    main()
      { enum coin money;
        for(money=penny;money<=dollar;money++)
          printf("%s  ",name[money]);
      }
程序运行结果如下:
 January
 February
 March
 April
 May
 June
 |