什么是结构体?
“结构”是一种构造类型,它是由若干“成员”组成的。每一个成员可以是一个基本数据类型或者又是一个构造类型。
为什么要有结构类型?
结构体可以把功能相同的数据组织起来,存在一起,用的时候方便,而且在调用函数时,若
传递参数较多,传一个结构体相对而言简单一些,很多系统自带的函数必须用结构体。
1、定义结构体的方法
定义一个结构的一般形式为:
struct 结构名
{
成员表列
};
//定义一个学生的结构
struct student { int num; char name[20]; //char *name; char sex; float score; };
成员表列由若干个成员组成,每个成员都是该结构的一个组成部分。对每个成员也必须作类 型说明,其形式为:
类型说明符 成员名;
成员名的命名应符合标识符的书写规定。
2.结构体变量及定义方法
1.先定义结构,再说明结构变量。
struct student { int num; char name[20]; //char *name; char sex; float score; }; strut student stu1,stu2;
也可以用宏定义使一个符号常量来表示一个结构类型。
#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
{
成员表列
}变量名表列;
第三种方法与第二种方法的区别在于第三种方法中省去了结构名,而直接给出结构变量,这种结构体最大的问题是,不能再次定义新的结构体变量了。
------------------结构体变量的初始化-------
1、先定义结构体变量,然后再初始化
struct stu { int num; char name[20]; char sex; float score; }; struct stu boy1,boy2; boy1.num = 1010; strcpy(boy1.name, "bbbbb"); //boy1.name="cjk"; //这是错误的 //相当于char name[20], name="abc"; //如果写成char *name, 则name="abc"可以; boy1.sex = 'f'; boy1.score = 18.0f;
2、定义的同时初始化
1)全部初始化 定义结构体的时候直接初始化
#include <stdio.h> #include <_string.h> struct stu { int num; char name[20]; char sex; float score; } av1={1012,"xzmly",'f',30}; //注意 "xzmly"初始化赋值给了name[20]; printf("av1.name=%s",av1.name); //初始化的顺序必须与结构体定义的时候成员的顺序一致 struct stu boy1={1011,"zbz",'f',23}; // 使用另外一已经存在的结构体初始化新的结构体
----------------结构体存储
结构名只能表示一个结构形式,编译系统并不对它分配内存空间。只有当某变量被说明为这
种类型的结构时,才对该变量分配存储空间。
结构体占用的内存空间是每个成员占用的字节数之和(考虑对齐问题)。
-------------------结构体的作用域问题
结构类型定义在函数内部的作用域与局部变量的作用域是相同的
函数外部定义的结构体类型类似全局变量
全局作用域:从定义的那一行开始直到本文件结束为止
---------------结构体数组--------------
1、结构数组概念
数组的元素也可以是结构类型的。因此可以构成结构型数组。结构数组的每一个元素都是具 有相同结构类型的下标结构变量。在实际应用中,经常用结构数组来表示具有相同数据结构的一 个群体。如一个班的学生档案,一个车间职工的工资表等。
2、结构数组定义
定义格式:
struct 结构名
{
成员表列
}数组名[数组长度];
-------------结构体数组定义:
结构体数组定义的第一种方式:
1)定义结构体的同时,定义数组
struct Student { int age; char *name; int s_no; float score; }stu[5];
2)先定义结构体,后定义数组
struct Student boy[5];
例如:定义一个长度为5的数组,其中每一个元素都是 stu结构类型
struct stu { int num; char *name; char sex; float score; }boy[5];
定义了一个结构数组boy,共有5个元素,boy[0]~boy[4]。每个数组元素都具有struct stu的结 构形式。
----------结构数组的初始化
1、定义结构体数组的时候,进行初始化
struct Student{ char name[20]; int age; }boys[3]={{"sb",18},{"zbz",38},{"cgx",28}};
2、定义的同时进行初始化
struct Student girls[2]={{"fengjie",18},{"cjk",28}};
3、先定义后初始化,整体赋值
struct Student ds[2]; ds[0]=(struct Student){"xzmly",18}; ds[1]=(struct Student){"bdjy",18};
4、先定义结构体数组,后初始化
struct Student stu[2]; //stu[0].name = "zhangsan"; //strcpy(stu[0].name,"zhangsan"); scanf("%s",stu[0].name);
-------------结构数组遍历
struct Student{ char name[20]; int age; }boys[3]={{"sb",18},{"zbz",38},{"cgx",28}}; for(int i=0;i<3;i++){ printf("name:%s,age:%d\n",boys[i].name,boys[i].age); }
----------------------结构指针定义和初始化 -----------------
1、指向结构体变量的指针
一个指针变量当用来指向一个结构变量时,称之为结构指针变量。结构指针变量中的值是所指向 的结构变量的首地址。通过结构指针即可访问该结构变量,这与数组指针和函数指针的情况是相 同的。
结构指针变量说明的一般形式为:
struct 结构名 *结构指针变量名
例如,在前面的例题中定义了stu这个结构,如要说明一个指向stu的指针变量pstu, 可写为:
struct stu *pstu; //定义了指针只能指向stu结构体类型的结构体变量
当然也可在定义stu结构时同时说明pstu。与前面讨论的各类指针变量相同,结构指针变量也必须 要先赋值后才能使用。
赋值是把结构变量的首地址赋予该指针变量,不能把结构名赋予该指针变量。
如果boy是被说明为stu类型的结构变量, 则:
pstu=&boy 是正确的,
而:
pstu=&stu 是错误的。
2、结构名、结构体变量名、结构体指针
结构名和结构变量是两个不同的概念,不能混淆。结构名只能表示一个结构形式,编译系统并不 对它分配内存空间。只有当某变量被说明为这种类型的结构时,才对该变量分配存储空间。结构 指针变量,就是用来存储结构体变量地址的,就能更方便地访问结构变量的各个成员。
------结构体指针间接访问成员值
其访问的一般形式为:
(*结构指针变量).成员名
或为:
结构指针变量->成员名
----------结构体嵌套使用
1)成员也可以又是一个结构,即构成了嵌套的结构
结构体嵌套:结构体定义的里面有其他结构体
结构体不可以嵌套自己变量,可以嵌套指向自己这种类型的指针
如:
struct Date { int month; int day; int year; } struct stu { int num; char *name; char sex; struct Date birthday; float score; }
------------------结构体指针作为函数的参数 -----------