C语言------结构体、枚举类型

 

一、结构体

   结构体的定义:

 

       在实际问题中,一组数据往往具有不同的数据类型。例如,在学生登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。显然不能用一个数组来存放这一组数据。因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,C语言中给出了另一种构造数据类型——“结构(structure)”或叫“结构体”。 它相当于其它高级语言中的记录。“结构”是一种构造类型,它是由若干“成员”组成的。每一个成员可以是一个基本数据类型或者又是一个构造类型。结构既是一种“构造”而成的数据类型,那么在说明和使用之前必须先定义它,也就是构造它。如同在说明和调用函数之前要先定义函数一样。

    定义一个结构的一般形式为

      struct 结构名

      {

           成员表列

        };

    成员表列由若干个成员组成,每个成员都是该结构的一个组成部分。对每个成员也必须作类型说明,其形式为:

        类型说明符 成员名;

    成员名的命名应符合标识符的书写规定。例如:

 struct stu
{
        int num;
        char name[20];
        char sex;
        float score;
};

 

          在这个结构定义中,结构名为 stu,该结构由4个成员组成。第一个成员为num,整型变量;第二个成员为name,字符数组;第三个成员为sex,字符变量;第四个成员为score,实型变量。应注意在括号后的分号是不可少的。结构定义之后,即可进行变量说明。凡说明为结构stu的变量都由上述4个成员组成。由此可见,结构是一种复杂的数据类型,是数目固定,类型不同的若干有序变量的集合。

    结构体变量的说明:

 

    说明结构变量有以下三种方法。以上面定义的stu为例来加以说明。

    1)先定义结构,再说明结构变量。

      如:

    

struct stu
{
        int num;
        char name[20];
        char sex;
        float score;
};
struct stu boy1,boy2;

    说明了两个变量boy1和boy2为stu结构类型。也可以用宏定义使一个符号常量来表示一个结构类型。

    例如:

#define STU struct stu

STU
{
        int num;
        char name[20];
        char sex;
        float score;
};
STU boy1,boy2;

    2)在定义结构类型的同时说明结构变量。

    例如:

struct stu
{
        int num;
        char name[20];
        char sex;
        float score;
}boy1,boy2;

    这种形式的说明的一般形式为:

      struct 结构名

     {

         成员表列 ......;

       }变量名表列;

 

     3) 直接说明结构变量。

     例如:

struct
{
        int num;
        char name[20];
        char sex;
        float score;
}boy1,boy2;

     这种形式的说明的一般形式为:

        struct

      {

         成员表列......;

        }变量名表列;

     第三种方法与第二种方法的区别在于第三种方法中省去了结构名,而直接给出结构变量。

 

     结构体变量的赋值:

 

     结构变量的赋值就是给各成员赋值。可用输入语句或赋值语句来完成。

main()
{
struct stu
{
      int num;
      char *name;
      char sex;
      float score;
} boy1,boy2;
    boy1.num=102;
    boy1.name="Zhang ping";
    printf("input sex and score\n");
    scanf("%c %f",&boy1.sex,&boy1.score);
    boy2=boy1;
    printf("Number=%d\nName=%s\n",boy2.num,boy2.name);
    printf("Sex=%c\nScore=%f\n",boy2.sex,boy2.score);
}

         本程序中用赋值语句给num和name两个成员赋值,name是一个字符串指针变量。用scanf函数动态地输入sex和score成员值,然后把boy1的所有成员的值整体赋予boy2。最后分别输出boy2的各个成员值。本例表示了结构变量的赋值、输入和输出的方法。

    结构体变量的初始化:

    和其他类型变量一样,对结构变量可以在定义时进行初始化赋值。

main()
{
struct stu    /*定义结构*/
{
      int num;
      char *name;
      char sex;
      float score;
}boy2,boy1={102,"Zhang ping",'M',78.5};
 boy2=boy1;
 printf("Number=%d\nName=%s\n",boy2.num,boy2.name);
 printf("Sex=%c\nScore=%f\n",boy2.sex,boy2.score);
}

  本例中,boy2,boy1均被定义为外部结构变量,并对boy1作了初始化赋值。在main函数中,把boy1的值整体赋予boy2,然后用两个printf语句输出boy2各成员的值。

  

 指向结构变量的指针:

 

   一个指针变量当用来指向一个结构变量时,称之为结构指针变量。结构指针变量中的值是所指向的结构变量的首地址。通过结构指针即可访问该结构变量,这与数组指针和函数指针的情况是相同的。

    结构指针变量说明的一般形式为:

       struct 结构名 *结构指针变量名

    例如,在前面的例题中定义了stu这个结构,如要说明一个指向stu的指针变量pstu,可写为:

        struct stu *pstu;

    当然也可在定义stu结构时同时说明pstu。与前面讨论的各类指针变量相同,结构指针变量也必须要先赋值后才能使用。赋值是把结构变量的首地址赋予该指针变量,不能把结构名赋予该指针变量。如果boy是被说明为stu类型的结构变量,则:

       pstu=&boy

是正确的,而:

       pstu=&stu

是错误的。

    结构名和结构变量是两个不同的概念,不能混淆。结构名只能表示一个结构形式,编译系统并不对它分配内存空间。只有当某变量被说明为这种类型的结构时,才对该变量分配存储空间。因此上面&stu这种写法是错误的,不可能去取一个结构名的首地址。有了结构指针变量,就能更方便地访问结构变量的各个成员。

其访问的一般形式为:

      (*结构指针变量).成员名

     或为:

       结构指针变量->成员名

     例如:

       (*pstu).num

     或者:

        pstu->num

     应该注意(*pstu)两侧的括号不可少,因为成员符“.”的优先级高于“*”。如去掉括号写作*pstu.num则等效于*(pstu.num),这样,意义就完全不对了。

struct stu
{
      int num;
      char *name;
      char sex;
      float score;
} boy1={102,"Zhang ping",'M',78.5},*pstu;
main()
{
    pstu=&boy1;
    printf("Number=%d\nName=%s\n",boy1.num,boy1.name);
    printf("Sex=%c\nScore=%f\n\n",boy1.sex,boy1.score);
    printf("Number=%d\nName=%s\n",(*pstu).num,(*pstu).name);
    printf("Sex=%c\nScore=%f\n\n",(*pstu).sex,(*pstu).score);
    printf("Number=%d\nName=%s\n",pstu->num,pstu->name);
    printf("Sex=%c\nScore=%f\n\n",pstu->sex,pstu->score);
}

   本例程序定义了一个结构stu,定义了stu类型结构变量boy1并作了初始化赋值,还定义了一个指向stu类型结构的指针变量pstu。在main函数中,pstu被赋予boy1的地址,因此pstu指向boy1。然后在printf语句内用三种形式输出boy1的各个成员值。从运行结果可以看出:

 结构变量.成员名

(*结构指针变量).成员名

 结构指针变量->成员名

这三种用于表示结构成员的形式是完全等效的。

 

 


二、枚举类型

 

     在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等。如果把这些量说明为整型,字符型或其它类型显然是不妥当的。为此,C语言提供了一种称为“枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。

 

    枚举类型的定义和枚举变量的说明:

    枚举的定义枚举类型定义的一般形式为:

   enum 枚举名{ 枚举值表 };

    在枚举值表中应罗列出所有可用值。这些值也称为枚举元素。

 

    枚举变量的说明

    如同结构和联合一样,枚举变量也可用不同的方式说明,即先定义后说明,同时定义说明或直接说明。

    设有变量a,b,c被说明为上述的weekday,可采用下述任一种方式:

        enum weekday{ sun,mou,tue,wed,thu,fri,sat };

        enum weekday a,b,c;

    或者为:

        enum weekday{ sun,mou,tue,wed,thu,fri,sat }a,b,c;

    或者为:

        enum { sun,mou,tue,wed,thu,fri,sat }a,b,c;

 

 

    枚举类型变量的赋值和使用:

    枚举类型在使用中有以下规定:

    枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。

    例如对枚举weekday的元素再作以下赋值:

        sun=5;

        mon=2;

        sun=mon;

    都是错误的

    枚举元素本身由系统定义了一个表示序号的数值,从0开始顺序定义为0,1,2…。如在weekday中,sun值为0,mon值为1,…,sat值为6。

main()
{
   enum weekday
  { 
     sun,mon,tue,wed,thu,fri,sat
   } a,b,c;
    a=sun;
    b=mon;
    c=tue;
    printf("%d,%d,%d",a,b,c);
}

    说明:

    只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。如:

        a=sum;

        b=mon;

    是正确的。而:

        a=0;

        b=1;

    是错误的。如一定要把数值赋予枚举变量,则必须用强制类型转换。

    如:

        a=(enum weekday)2;

    其意义是将顺序号为2的枚举元素赋予枚举变量a,相当于:

        a=tue;

    还应该说明的是枚举元素不是字符常量也不是字符串常量,使用时不要加单、双引号。

 

 

    类型定义符typedef:

 

    C语言不仅提供了丰富的数据类型,而且还允许由用户自己定义类型说明符,也就是说允许由用户为数据类型取“别名”。类型定义符typedef即可用来完成此功能。

    例如,有整型量a,b,其说明如下:

        int a,b;

    其中int是整型变量的类型说明符。int的完整写法为integer,为了增加程序的可读性,可把整型说明符用typedef定义为:

        typedef int INTEGER

    这以后就可用INTEGER来代替int作整型变量的类型说明了。

    例如:

        INTEGER a,b;

    它等效于:

        int a,b;

    用typedef定义数组、指针、结构等类型将带来很大的方便,不仅使程序书写简单而且使意义更为明确,因而增强了可读性。

    例如:

    typedef char NAME[20];    表示NAME是字符数组类型,数组长度为20。然后可用NAME 说明变量,如:

    NAME a1,a2,s1,s2;

完全等效于:

    char a1[20],a2[20],s1[20],s2[20]

又如:

    typedef struct stu

    { char name[20];

      int age;

      char sex;

           } STU;

    定义STU表示stu的结构类型,然后可用STU来说明结构变量:

        STU body1,body2;

        typedef定义的一般形式为:

        typedef 原类型名 新类型名

    其中原类型名中含有定义部分,新类型名一般用大写表示,以便于区别。

    有时也可用宏定义来代替typedef的功能,但是宏定义是由预处理完成的,而typedef则是在编译时完成的,后者更为灵活方便。

 


你可能感兴趣的:(C语言)