什么是结构体?
“结构”是一种构造类型,它是由若干“成员”组成的。每一个成员可以是一个基本数据类型或者又是一个构造类型。
为什么要有结构类型?
结构体可以把功能相同的数据组织起来,存在一起,用的时候方便,而且在调用函数时,若
传递参数较多,传一个结构体相对而言简单一些,很多系统自带的函数必须用结构体。
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;
}
------------------结构体指针作为函数的参数 -----------