为什么需要结构体
为了表示一些复杂的事务,而普通的基本类型无法满足实际要求
什么叫结构体
把一些基本类型数据组合在一起形成的一个新的复合数据类型,这个叫结构体
如何定义结构体
3种方式:
// 第一种方式
struct Student
{
int age;
float score;
char sex;
};
// 第二种方式:定义结构体的同时,定义变量名
struct Student2
{
int age;
float score;
char sex;
} st2;
// 第三种方式:没有类型名
struct
{
int age;
float score;
char sex;
} st3;
怎样使用结构体变量
赋值和初始化
# include <stdio.h>
// 第一种方式 这里只是定义了一个新的数据类型,并没有定义变量
struct Student
{
int age;
float score;
char sex;
};
int main(void)
{
struct Student st = {80, 66.6, 'F'}; //初始化 定义的同时赋初值
struct Student st2; // 先定义变量,再赋值
st2.age = 10;
st2.score = 88.0;
st2.sex = 'M';
printf("%d %f %c\n", st.age, st.score, st.sex);
printf("%d %f %c\n", st2.age, st2.score, st2.sex);
return 0;
}
定义的同时可以整体赋初值
如果定义完之后,则只能单个的赋初值
如何取出结构体变量中的每一个成员
- 结构体变量名.成员名
- 指针变量 -> 成员名
# include <stdio.h>
// 第一种方式
struct Student
{
int age;
float score;
char sex;
};
int main(void)
{
struct Student st = {80, 66.6, 'F'}; //初始化 定义的同时赋初值
struct Student *pst = &st;
st.age = 10; // 第一种方式
pst->age = 88; //第二种方式
return 0;
}
pst->age 在计算机内部会被转化成 (*pst).age,没有什么为什么,这就是->的含义,这也是一种硬性规定。
所以 pst->age 等价于 (*pst).age 也等价于 st.age
pst->age 的含义:pst所指向的那个结构体变量中的age成员
结构体变量的运算
结构体变量不能相加,不能相减,也不能乘除,但是结构体变量可以相互赋值
struct Student st1, st2;
st1 = st2;
结构体变量与结构体指针变量作为函数参数传递的问题
# include <stdio.h>
# include <string.h>
struct Student {
int age;
float score;
char name[100];
};
void InputStu(struct Student *);
void OutputStu(struct Student);
int main(void)
{
struct Student st;
InputStu(&st); // 对结构体变量输入 必须发送st的地址
OutputStu(st); // 对结构体变量输出 可以发送st的地址,也可以直接发送st的内容
return 0;
}
// 输入结构体成员的值
void InputStu(struct Student *pst) //pst只占4个字节
{
pst->age = 27; // 等价于 (*pst).age = 27
pst->score = 66.6f;
strcpy(pst->name, "李勇");
}
//输出结构体成员
void OutputStu(struct Student s)
{
printf("name = %s, age = %d, score = %f\n", s.name, s.age, s.score);
}
推荐使用结构体指针变量作为函数的参数来传递
冒泡排序
# include <stdio.h>
void sort(int *, int);
int main(void)
{
int a[5] = {8, 4, 6, -7, 3};
int i;
sort(a, 5);
for (i=0; i<5; i++)
printf("%d ", a[i]);
return 0;
}
void sort(int * pArr, int len)
{
int i, j, t;
for (i=0; i<len-1; i++)
{
for (j=0; j<len-1-i; j++)
{
if (pArr[j] > pArr[j+1])
{
t = pArr[j];
pArr[j] = pArr[j+1];
pArr[j+1] = t;
}
}
}
}
解读:我们要对一维数组的5个元素进行排序,要进行4外循环,里面的循环需要比较len-1-i次。并且每一次都是前一个元素与后面一个元素进行比较,如果前一个数大于后一个数,则交换位置,否则就不用。
举例:动态构造存放学生信息的结构体数组
动态构造一个数组,存放学生的信息,然后按分数排序输出
# include <stdio.h>
# include <malloc.h>
struct Student{ // 定义结构体
int age;
float score;
char name[100];
};
//函数声明
void InputStu(struct Student *, int);
void sort(struct Student *, int);
void OutputStu(struct Student *, int);
int main(void)
{
int len; // 数组的长度
struct Student * pArr = (struct Student *)malloc(sizeof(struct Student) * len); // 动态创建一个结构体的一维数组,用来存放学生的信息
// 手动输入数组的长度
printf("请输入学生的个数:\n");
printf("len = ");
scanf("%d", &len);
// 输入学生的信息
InputStu(pArr, len);
// 排序,按学生的成绩排序
sort(pArr, len);
printf("\n\n");
// 输出学生的信息
OutputStu(pArr, len);
return 0;
}
/*
参数:pArr是一个struct Student类型的指针变量,用来存放 struct Student类型变量的地址,len 是数组的长度
功能: 向类型为struct Student,长度为len的一维数组中,写入数据
*/
void InputStu(struct Student *pArr, int len)
{
int i;
for (i=0; i<len; i++)
{
printf("请输入学生年龄:\n");
printf("age = ");
scanf("%d", &pArr[i].age);
printf("请输入学生姓名:\n");
printf("name = ");
scanf("%s", pArr[i].name);
printf("请输入学生分数:\n");
printf("score = ");
scanf("%f", &pArr[i].score);
}
}
/*
功能:对数组进行排序,排序条件Wie结构体变量的score成员
*/
void sort(struct Student * pArr, int len)
{
int i, j;
struct Student t;
for (i=0; i<len-1; i++) {
for(j=0; j<len-1-i; j++) {
if (pArr[j].score > pArr[j+1].score) {
t = pArr[j];
pArr[j] = pArr[j+1];
pArr[j+1] = t;
}
}
}
}
/*
功能:把一维结构体数组的成员信息输出到控制台
*/
void OutputStu(struct Student *pArr, int len)
{
int i;
for (i=0; i<len; i++)
{
printf("第%d个学生的信息:\n", i+1);
printf("age = %d\n", pArr[i].age);
printf("name = %s\n", pArr[i].name);
printf("score = %f\n", pArr[i].score);
printf("\n");
}
}