C语言复习3----结构体
结构体类型概述 前面章节学过的数组是一组同类型数据的集合。一个数组只能存放同一种类型的数据,不同类型的数据不能放在一个数组。 而结构体由不同的数据类型组成,例如学生的姓名、学生证号、年龄、手机号码等,这就需要结构体数据类型。 结构体不是一种新的数据类型,而是把其它不同的数据类型组合起来,是由其它类型构造出来,因此称为构造类型。
结构体类型 1)结构体由若干个数据项组成,每个数据项称为结构体的一个成员,每个数据项属于一种已有的数据类型。 2)结构体类型是由不同类型的数据项组成的复合类型。 结构体类型的定义格式: struct 结构体类型名 { 数据类型1 成员1名; 数据类型2 成员2名; . 数据类型n 成员n名; }; 成员列表
定义一个学生的结构体 例如定义一个学生的结构体: struct student { int number; char name[15]; char sex; int age; } 成员又称为成员变量,是结构体中若干个数据类型,每个成员须标明数据类型。
构体类型的嵌套 struct date { int year; int month; int day; }; struct person int number; char name[20]; char sex; struct date birthday; 结构体成员可以是任意的数据类型,还可以是其它的结构体类型,这时称为结构体类型的嵌套。
结构体变量的定义 在定义了结构体之后,结构体变量可以用三种方式定义。 方式1: 先声明结构体类型,再定义变量名,分别定义。 struct student { int number; char name[15]; char sex; int age; } 用上面定义的结构体struct student来定义结构体变量 struct student stu1,stu2; 定义了stu1和stu2为struct student类型的变量。 定义结构体变量之后,C系统就为它们分配内存单元。
方式2:结构体类型和结构体变量名一起定义 struct student { int number; char name[15]; char sex; int age; }stu1,stu2;
方式3:省略结构体类型名,直接定义结构体变量 struct { int number; char name[15]; char sex; int age; }stu1,stu2;
结构体变量的初始化 定义了结构体变量之后,就可对变量赋值或存取。 对于结构体和结构体变量名分别定义,可以这样来初始化: struct student stu1={001,'david','M',25,}; 结构体和结构体变量名一起定义,可以这样来初始化: struct student { int number; char name[15]; char sex; int age; }stu1={001,'david','M',25,};
printf("%d,%s,%c,%d\n",stu1)--------错误 结构体变量的引用 定义了结构体变量之后,就可以在程序中引用它了。 能够引用的对象有两个:结构体变量名代表变量整体,成员名代表变量的各个成员。引用时注意: 1)不能将一个结构体变量作为一个整体进行输入和输出,如: printf("%d,%s,%c,%d\n",stu1)--------错误 只能对结构体的成员变量输入输出。引用结构体变量中的成员变量的方式为: 结构体变量名.成员变量 如: stu1.name
成员本身又是一个结构体 struct date { int year; int month; int day; }; strcut stu { int number; char name[15]; char sex; struct date birthday; /*成员本身又是一个结构体*/ }student; 2)如果成员本身又是一个结构体,要一级一级找到最低的成员变量,只能对最低的成员进行赋值或运算。 可以这样来引用:student.birthday.month
3)结构体变量可以整体赋值。例如stu1=stu2,把变量stu2的所有成员的值一一赋值给变量stu1,但是这两个结构体变量的类型必须完全相同。 4)结构体变量占据的一段内存的首地址称为该结构体变量的地址,其每个成员占据的若干个单元的首地址称为该成员的地址。
结构体数组 以上定义的存放学生信息的结构体类型struct student,可以定义1个变量stu,但是只能存放stu的1个学生的信息。如果为了能放10个学生信息就要定义10个结构体变量,不现实。 为了处理多个学生信息,就要用到结构体数组。 对于结构体数组来说,其中每一个单元都是一个结构体类型的数据。
结构体数组的定义 结构体数组的定义也可以采用以下3种方式之一: 1)定义结构体类型,然后通过结构体类型来定义结构体数组 struct stu { long num; char name[10]; char sex; int age; }; struct stu students[20] 这里结构体数组students有20个单元,每一个单元都是一个struct stu类型。
2)结构体类型与结构体数组同时定义 struct stu { long num; char name[10]; char sex; int age; }students[20]
3)直接定义结构体数组 而不用定义结构体类型名 struct { long num; char name[10]; char sex; int age; }students[20]
结构体数组的初始化 结构体数组的初始化,每个元素的初值是由{ }括起来的1组数据,在定义结构体数组时加在后面。 例如: struct syu students[2] ={{001,"David",'M',25}, {002,"Lily",'W',23}};
结构体数组的引用 结构体数组元素不能作为一个整体进行输入或输出,引用结构体数组的成员同普通数组的成员一样。 例如:student[0].num。
结构体和指针 结构体数组占据一段内存,结构体数组名代表这段内存的首地址,我们可以把这结构体数组的首地址赋给一个指针,这个指针就是指向结构体类型数据的指针。
指向结构体变量的指针 先定义一个结构体stu,再定义一个指向结构体的指针p,例如 : struct stu *p; 定义结构体变量students ,然后让这个指针p指向这个变量,例如: struct stu students ; p=&students; 这个指针p就指向结构体变量students。就可以把students.num表示为(*p).num。 可以把(*p).num用指向运算符来表示,表示为: p->num。
引用成员变量的三种方式: 1)结构体变量.成员变量 2)(*p).成员变量 3)p->成员变量 其中3)指向运算符的优先级是最高的。
指向结构体数组的指针 指向结构体数组的指针与指向普通数组的指针完全一样。 与普通数组一样,p++并不是指针指向内存的下一个位置,而是指向结构体数组的下一个单元。
指向结构体的指针作为函数参数 程序设计经常需要把结构体类型的数据传递给一个函数。把一个结构体类型的变量或数组传给函数,可以有三种方式: 1)用结构体成员变量作为函数的参数,是值传递方式。 2)用结构体变量作为实参,也是传值方式。 3)用指向结构体变量的指针作为实参,把结构体变量的地址传递给形参。
共同体 使几种不同类型的变量占用同一段内存的结构,称为“共同体”类型结构。 例如: union data 定义共同体类型的形式为: { 成员列表 }变量列表 例如: union data { int i; char ch; float f; }; union data a,b,c; //先声明一个共同体data //再定义变量a,b,c
共同体与结构体的不同 结构体变量所占内存是各成员占的内存长度之和。 而共同体变量所占内存长度是其中最长的成员的长度。 同一段内存段虽然可以存放几种不同类型的成员,但不能同时存放,起作用的成员是最后一次存放的成员,在存入一个新的成员后,原有的成员就被冲掉。 各成员的地址都是同一地址。
用typedef定义类型 除了C的标准类型(int,char,float,double,long)外,以及自己定义的结构体、共同体、指针等,还可以用typedef声明新的类型名来代替已有的类型名。例如: typedef int INTEGER; typedef float REAL; 指定用INTEGER来代替int,用REAL来代替float。
用typedef声明结构体类型 typedef struct date { int month; int day; int year; 声明新类型名DATE,它代表上面指定的结构类型体,但只是个别名,不是结构变量,还不能直接使用。这时就可以用DATE来定义结构体变量: DATE birthday DATE *p;