十二、结构体与共用体

1、结构体

一般形式:  struct  结构名

                   {

                           成员列表;

                   };

成员列表由若干个成员组成,每个成员必须作类型说明: 类型说明符  成员名;

(1)定义结构体类型变量的方法:

a.  先声明结构体类型再定义变量名 

    例: struct  student

             {

                   int  num ;

                  char  name[ 20 ] ;

                  char  sex ;

             } ;

            struct  student  student1 , studnet2;          //student1 和 student2 为变量名

b.  在声明类型的同时定义变量

     例: struct  student

              {

                   int  num ; 

                   char name[ 20 ] ;

                   char sex ;

              } student1 , student2 ;

c.  直接定义结构体类型变量(即不出现结构体名)

     一般形式:  struct 

                      {

                            成员列表;

                      } 变量名列表;

 

(2)结构体的嵌套

例:            十二、结构体与共用体_第1张图片十二、结构体与共用体_第2张图片

 

(3)结构体变量的引用

a.  不能将一个结构体变量作为一个整体进行输入和输出

     正确引用结构体变量中成员的方式为:结构体变量名 . 成员名

     例:打印 student1 中变量的值             student1.num 

     赋值:student.1num = 100 ;

b.  只能对最低级的成员进行赋值或存取以及运算 

c.  对结构体变量的成员可以像普通变量一样进行各种运算

d.  可以引用结构体变量成员的地址,也可以引用结构体变量的地址,结构体变量的地址主要用作函数参数,传递结构体变量的地址

e.  " 不能 "这样读入结构体变量   scanf ( " %d , %s , %c , %f " , &student1 ) ;要精确到最小的一个级别

(3)结构体变量的初始化

十二、结构体与共用体_第3张图片

 

(4)结构体数组

定义结构体数组:

十二、结构体与共用体_第4张图片

 

 

结构体数组的初始化:

十二、结构体与共用体_第5张图片

 

十二、结构体与共用体_第6张图片

 

(5)指向结构体类型数据的指针

a.  一个结构体变量的指针就是该结构体变量所占据的内存段的起始地址

b.  可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址

c.  指针变量也可以用来指向结构体数组中的元素

d.  结构体指针变量说明的一般形式为: struct  结构名  *结构指针变量名    例:struct  stu  *pstu ;

e.  赋值时把结构变量的首地址赋予该指针变量,不能把结构名赋予该指针变量,如果 boy 时被说明为 stu 类型的结构变量,则:

    pstu = &boy 是正确的       pstu = &stu 是错误的

f.  结构名和结构变量是两个不同的概念,结构名只能表示一个结构形式,编译系统并不对它分配内存空间

g.  只有当某变量被说明为这种类型的结构时,才对该变量分配存储空间

h.  一般访问形式: ( *结构指针变量 ) . 成员名     或     结构指针变量 - > 成员名     例:( *pstu ).num 或 pstu->num

(6)结构指针变量作函数参数

十二、结构体与共用体_第7张图片

 

二、动态存储分配

常用的内存管理函数有三个:(1)分配内存空间函数 malloc、calloc

                                               (2)释放内存空间函数 free

 

十二、结构体与共用体_第8张图片十二、结构体与共用体_第9张图片

 

十二、结构体与共用体_第10张图片

 

三、链表

(1)链表是一种常见的重要的数据结构,是动态地进行存储分配的一种结构

(2)链表的组成:   头指针:存放一个地址,该地址指向第一个元素

                                  结点:用户需要的实际数据和链接节点的指针

             例:                十二、结构体与共用体_第11张图片

(3)建立动态链表

         动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系

         例:建立一个含有学生(学号,成绩)数据的单向动态链表,约定学号不会为0,如果输入的学号为0则表示建立链表的过程完成,该结点不会链接                    到链表中

                提示图 

                                             十二、结构体与共用体_第12张图片

(4)实现链表输出

         a.  先知道链表第一个结点的地址,也就是 head 的值

         b.  然后设一个指针标量 p ,先指向第一个结点,输出 p 所指的指点,然后使 p 后移一个结点,再输出,直到链表的尾结点

         流程图:

                         十二、结构体与共用体_第13张图片十二、结构体与共用体_第14张图片

(5)对链表的删除操作

         从动态链表中删去一个结点,并不是真正从内存中把它抹掉,而是把它从链表中分离开来,只要撤销原来的链接关系即可

        思路:a.  从 p 指向的第一个结点开始,检查该结点中的 num 值是否等于输入的要求删除的那个值

                   b.  如果相等就将该结点删除,如不相等,就将 p 后移一个结点,再如此进行下去,直到表尾为止

                   c.  可以设两个指针变量 p1 和 p2 ,先使 p1 指向第一个结点

                   d.  如果要删除的不是第一个结点,则使 p1 后移指向下一个结点(将 p1 -> next 赋给 p1),在此之前将 p1 的值赋给 p2 ,使 p2 指向刚才检                            查过的那个结点

                  流程图: 

                                  十二、结构体与共用体_第15张图片

(6)对链表的插入操作

         指将一个结点插入到一个已有的链表中

         思路:先用指针变量 p0 指向待插入的结点,p1 指向第一个结点。将 p0 - >num 与 p1 - >num 相比较,如果 p0 - >num > p1 - >num ,此时将 p1 后                      移,并使 p2 指向刚才 p1 所指的结点 

         三种情况:

                            十二、结构体与共用体_第16张图片

         提示图:

                            十二、结构体与共用体_第17张图片

 

四、共用体

(1)概念:使几个不同的变量共占同一段内存的结构

(2)一般形式: union  共用体名

                            {

                                   成员列表;

                            }变量列表;

        例:            

                       十二、结构体与共用体_第18张图片

(3)共用体和结构体的比较

         结构体变量所占内存长度是各成员占的内存长度之和,共用体变量所占的内存长度等于最长的成员的长度

         例:  union data

                  {

                        int  i ;                 //占4个字节

                       char  ch ;           //占1个字节 

                       float  f ;              //占4个字节

                  }                             //共占4个字节,而不是4+1+4=9

(4)共用体变量的引用

         先定义了共用体变量才能引用,但不能引用共用体变量,只能引用共用体变量中的成员

        例:定义 a,b,c为共用体变量      a.i(引用共用体变量中的整型变量 i )

                                                                a.ch(引用共用体变量中的字符变量 ch )

                                                                a.f(引用共用体变量中的实型变量 f )

(5)共用体类型数据的特点

         a.  同一个内存可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种

         b.  共用体变量中起作用的成员时最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用

         c.  共同体变量的地址和它的各成员的地址都是同一地址

         e.  不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,也不能在定义共用体变量时对它初始化

         f.  不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可以使用指向共用体变量的指针

         g.  共用体类型可以出现在结构体类型定义中,也可以定义共用体数组

         例:

                   十二、结构体与共用体_第19张图片

                   十二、结构体与共用体_第20张图片

                   十二、结构体与共用体_第21张图片

五、枚举类型

(1)在实际问题中,有些变量的取值被限定在一个有限的范围内    例如 一星期有7天

(2)枚举变量的声明:

             十二、结构体与共用体_第22张图片

(3)注意:

         a.  在“枚举”类型的定义中列举所有可能的取值,不能超过定义范围

         b.  枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型

         c.  枚举值表中应列出所有可用值,这些值叫枚举元素

         d.  在C编译中,对枚举元素按常量处理,故称为枚举常量。但它们不是变量,不能对他们赋值

         e.  枚举值可以作判断比较,一个整数不能直接赋给一个枚举变量

              例:

                          十二、结构体与共用体_第23张图片

 

六、typedef 定义类型

(1)用 typedef 声明新的类型名来代替已有的类型名

(2)声明 INTEGER 为整型:  typedef  int  INTEGER ;

(3)声明结构类型: Typedef  struct {

                                   int  month ; 

                                   int  day ;

                                   int  year ; 

                                   } DATE ;

         例:

                    十二、结构体与共用体_第24张图片

(4)

             十二、结构体与共用体_第25张图片

             十二、结构体与共用体_第26张图片

(5)注意:

         a.  用 typedef 可以声明各种类型名,但不能用来定义变量

         b.  用 typedef 只是对已经存在的类型增加一个类型名,而没有创造新的类型

(6)宏定义表示数据类型和用 typedef 定义数据说明符的区别:

         宏定义只是简单的字符串代换,是在预处理完成的,而 typedef 是在编译时处理的,它不是简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。typedef 后面加分号。

         例: #define PIN1 char*

                 typedef char* PIN2;

                 PIN1 x,y;                       (相当于 char *x , y)

                 PIN2 a.b;                       (相当于 char *a , *b)

                 printf ( " By #define : %d %d \n\n",sizeof (x) , sizeof (y) ) ;

                 printf ( " By typedef : %d %d \n\n",sizeof (a) , sizeof (b) ) ;

                 输出结果为:  By #define : 4  1 

                                        By typedef : 4  4

 

       

 

 

 

 

 

 

       

 

 

 

 

              

 

 

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