4.指针与结构体
- 结构体类型是不同数据类型变量的集合。
- 结构体成员可以是任意合法的c语言数据类型定义的变量,但不能是自身结构体类型的变量,可以是指向自身结构体的指针。
- 结构体成员可以是结构体类型的变量,也可以是共用体类型的变量。
- 结构体类型的定义可以放在函数内,也可以放在函数外。
- 结构体所有成员一直驻留内存,一个结构体变量所占用的内存空间是该结构体类型中各个成员所占内存空间之和。
- 结构体变量不能作为一个整体进行引用,只能引用结构体变量中的成员。
4-1结构体类型
定义一般形式:
struct 结构体名
{
类型说明符1 成员名1;
类型说明符2 成员名2;
};
其中,struct是C语言中的关键字,指明后面出现的标识符是一个用户定义的结构体类型的名字、结构体名是合法的用户自定义的C标识符,花括号“{}”是结构体类型的定界符,花括号中给出该结构体包含的数据项,称为结构体成员,每个成员都要有自己的数据类型,可以是C语言允许的任何数据类型;花括号后的分号“;”是结构体类型定义的结束符。
例如:
struct Employee /*struct 是关键字, struct Employee 是结构体类型名*/
{
char name [20]; /*name,department,address,age和 email是结构体成员名*/
char department [ 30] ;
char address[30] ;
int age;
char email [30];
};
定义了一个结构体类型,用于描述职员通信表。结构体名是 Employee,包含6个成员,分别是name,department,address,age和 email,类型分别为字符数组、字符数组、字符数组、整型、字符数组。
定义结构体类型时,必须要有定界符“{}”与结束符“;”,它们是结构体类型定义时不可缺少的组成部分。 同一结构体类型内的成员名不能相同,但是不同结构体类型中的成员名可以相同。
4-2结构体类型变量
定义一般形式:
定义 | 举例 | |
声明结构体类型的同时定义变量 | struct 结构体名 { 成员列表 }变量名列表; | struct Emp { char name [20]; char department [ 30] ; char address[30] ; int age; char email [30]; }emp1,emp2[20],*emp3; |
直接定义变量【不能定义更多的变量】 | struct { 成员列表 }变量名列表; |
struct { char name [20]; char department [ 30] ; char address[30] ; int age; char email [30]; }emp1,emp2[20],*emp3; |
先声明结构体类型,后定义变量 | struct 结构体名 { 成员列表 }; struct 结构体名 变量名列表; | struct Emp { char name [20]; char department [ 30] ; char address[30] ; int age; char email [30]; }; struct Emp emp1,emp2[20],emp3; |
/*struct 是关键字, struct Employee 是结构体类型名*/ /*name,department,address,age和 email是结构体成员名*/ /*emp1结构体类型变量名,emp2结构体类型数组名, *emp3结构体类型指针变量*/ /* 结构体类型变量的引用:结构体变量名.成员名;emp1.age; 结构体类型数组的引用:数组名[下标].成员名;emp2[6].age; 结构体类型指针变量的引用:{*结构体类型指针变量}.成员名;{*emp3}.age; 结构体类型指针变量->成员名;emp3->age; */ |
4-3.指向结构体类型变量的指针
结构体类型变量也有地址,指向结构体类型变量的指针中存放一个结构体类型变量所占内存单元的首地址,指向结构体类型变量的指针的说明形式为:
结构体类型说明符 *指针变量名;
例如:
struct student{ char name[ 15];
int age;
float score;
} s,*p=Null; /*定义结构体类型的变量及指向结构体类型变量的指针*/
- 定义好一个指向结构体类型变量的指针之后,C编译程序只给其分配了一个用于存放地址的空间,但它并没有具体的指向,必须将一个结构体类型变量的地址或结构体类型数组元素的地址赋给它。
- 结构体类型变量的地址必须通过取地址符“&”取得。如:p=&s;
- 用结构体类型变量引用结构体成员是以圆点作为连接符的。如:s.name; s.age;
- 通过指向结构体类型的指针引用结构体成员,有两种方法:一种是用圆点操作符“.”;另一种是用箭头操作符“->”。如:(*p).name; p->name;
- 不可以写成*p.name。因为“.”的优先级高于*。【“(*p).name”的表达式先做(*p)运算,而“*p.name”表示先做(p.name)运算】p是一个指向结构体变量的指针变量p指向s时(即p=&s),(*p)与s等价。
- “->”优先级最高。指向结构体的指针变量p中储存的是结构体变量的地址,p是指向结构体变量。
4-4.指向结构体类型数组的指针
如果将结构体数组中某一元素的地址赋给指向结构体类型的指针变量,那么指向结构体类型的指针在进行加1之后可以指向数组的下一元素。如此重复就可以用指向结构体的指针变量对结构体数组元素进行操作。
例如:
struct student
{ char name[ 15];
int age;
float score;
} ;
struct student stu[20],*p;
p=stu;
/*
p将指向stu数组的首地址,也就是stu[0]的地址,p->name表示stu[0].name。
执行“p++;”后,p将指向stu数组中的元素stu[1],p->name表示stu[1 ].name。
*/
4-5结构体成员引用
- 结构体变量名.成员名;【.前面必须是变量名】
- {*结构体类型指针变量}.成员名;
- 结构体类型指针变量->成员名;【->前面必须是指针名】
struct student
{ char name[ 15];
int age;
float score;
} s,*p; /*s结构体类型变量名, *p结构体类型指针变量*/
赋值:p->age=18;等价于(*p).age=18;等价于s.age=18;
p->name="lili";【p->name是地址常量,不能放等号左边】
使用指针还可以处理链表