一,介绍
设计一个结构体指针变量,每个变量保存的是学号(整数),姓名(字符串),分数(浮点数)
二,代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct stu
{
int num;
char *name; // 指针成员,保存的是外部字符串的首元素地址
float score;
} STU;
void test01()
{
// 结构体数组在 堆区
STU *edu = (STU *)calloc(5, sizeof(STU));
if (NULL == edu)
{
return;
}
int n = 3;
// 为数组的每个元素中的 name 申请堆区
int i = 0;
for (i = 0; i < n; i++)
{
(edu + i)->name = (char *)malloc(32);
if (NULL == (edu + i)->name)
return;
}
// 获取键盘输入
for (i = 0; i < n; i++)
{
scanf("%d %s %f", &(edu + i)->num, (edu + i)->name, &(edu + i)->score);
}
// 输出
for (i = 0; i < n; i++)
{
printf("%d %s %f\n", (edu + i)->num, (edu + i)->name, (edu + i)->score);
}
// 释放指针成员 指向的空间
for (i = 0; i < n; i++)
{
if ((edu + i)->name != NULL)
{
free((edu + i)->name);
(edu + i)->name = NULL;
}
}
// 释放结构体数组的空间(堆区)
if (edu != NULL)
{
free(edu);
edu = NULL;
}
}
int main(int argc, char const *argv[])
{
test01();
return 0;
}
三,输出结果
四,解析
这段代码使用了动态内存分配来创建一个包含学生信息的结构体数组,并通过键盘输入为每个学生的成员赋值。然后,它输出了每个学生的信息,并在最后释放了动态分配的内存。
让我们逐步详细解释这段代码的每个部分:
-
定义了一个名为
STU
的结构体,它包含了学生的学号(num
)、姓名(name
)和分数(score
)。 -
在
test01
函数中,通过调用calloc
函数动态分配了一个包含5个STU
结构体的内存块,并将其赋值给指针变量edu
。calloc
函数会将分配的内存块初始化为0。 -
接下来,代码检查了内存分配是否成功。如果
edu
指针为NULL
,说明内存分配失败,函数使用return
语句提前结束函数的执行,并将控制权返回到调用者。 -
在循环中,为每个学生的
name
成员动态分配了32个字节的内存,并将其赋值给相应的指针。 -
然后,通过调用
scanf
函数从键盘输入每个学生的学号、姓名和分数。 -
接下来,使用循环遍历结构体数组,并使用
printf
函数输出每个学生的学号、姓名和分数。 -
在最后一个循环中,释放了每个学生的
name
成员所指向的内存。首先检查name
指针是否为NULL
,以避免释放无效的内存。如果name
指针不为NULL
,则使用free
函数释放内存,并将name
指针设置为NULL
。 -
最后,检查
edu
指针是否为NULL
,以避免释放无效的内存。如果edu
指针不为NULL
,则使用free
函数释放结构体数组所占用的内存,并将edu
指针设置为NULL
。 -
在
main
函数中,调用了test01
函数,并返回0表示程序正常结束。
这段代码的作用是创建一个包含学生信息的结构体数组,并通过键盘输入为每个学生的成员赋值。然后,它输出了每个学生的信息,并在最后释放了动态分配的内存,以避免内存泄漏。