结构体(struct)
结构体是C语言中用于组合多个不同类型变量的复合数据类型。通过结构体可以将逻辑相关的数据封装在一起,便于管理和操作。
定义语法:
struct 结构体名 {
数据类型 成员1;
数据类型 成员2;
// ...
};
示例:
struct Student {
char name[50];
int age;
float score;
};
结构体变量通过点运算符(.
)访问成员,结构体指针通过箭头运算符(->
)访问成员。
位域(Bit-field)
位域是结构体的扩展功能,允许按比特位分配成员的内存空间,用于节省存储或直接操作硬件寄存器。
定义语法:
struct 结构体名 {
数据类型 成员名 : 位数;
// ...
};
示例:
struct Status {
unsigned int flag1 : 1; // 1位
unsigned int flag2 : 3; // 3位
};
位域成员不能取地址,且位数不能超过成员数据类型的长度。
共用体(union)
共用体是一种特殊的数据类型,允许在相同内存位置存储不同的数据类型,但同一时间只能使用其中一个成员,所有成员共享同一段内存。
定义语法:
union 共用体名 {
数据类型 成员1;
数据类型 成员2;
// ...
};
示例:
union Data {
int i;
float f;
char str[20];
};
共用体常用于节省内存或处理多种数据类型交替存储的场景(如协议解析)。
枚举(enum)
枚举用于定义一组命名的整数常量,提高代码可读性。枚举常量默认从0开始递增,也可显式赋值。
定义语法:
enum 枚举名 { 枚举常量1, 枚举常量2, ... };
示例:
enum Week { Mon, Tue, Wed, Thu = 10, Fri };
// Mon=0, Tue=1, Wed=2, Thu=10, Fri=11
枚举变量只能赋值为枚举定义的常量,常用于状态机或选项标识。
关键区别
- 结构体:成员独立占用内存,总和为各成员大小之和。
- 共用体:成员共享内存,大小为最大成员的大小。
- 位域:指定成员占用的比特位数,仅用于结构体。
- 枚举:定义一组关联的整型常量,不直接占用结构体或共用体的内存。
作业:
1. 有若干个学校人员的信息,包括学生和教师。其中学生的数据包括:姓名、性别、职业s/S、分数。教师的数据包括:姓名、性别、职业t/T、职务。
1,定义结构体指针指向堆区的n个连续的内存空间 (封装函数:返回p指针,参数无)
2. 向堆区内存循环输入人员信息(如果job=='s'||job=='S',则输入分数,否则输入position)封装函数(参数:p,n 返回值:无)
3.计算老师的个数,学生的个数 无返封装函数(参数:p,n) 返回值:无
4.循环输出所有信息封装函数:(参数p,n 返回值:无
5.释放堆区内存
//main.c
#include "Person.h"
int main(int argc, const char *argv[])
{
//堆区空间申请函数
Personptr Per=Person_List_Found();
//人员信息输入函数
Person_Input(Per,5);
//统计老师个数和学生个数函数
Person_TnumorSnum(Per,5);
//统计男女人数函数
Person_MnumorWnum(Per,5);
//人员信息输出函数
Person_Output(Per,5);
//堆区空间释放函
Per=Person_List_Free(Per);
return 0;
}
//Person.h
#ifndef PERSON_h
#define PERSON_h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
typedef union Dfifferent
{
float score;
char position[100];
}Dfifferent;
typedef struct Person
{
char name[100];
char sex[10];
char job;
Dfifferent diff;
}Person,*Personptr;
//堆区空间申请函数
Personptr Person_List_Found();
//人员信息输入函数
void Person_Input(Personptr Per,int n);
//统计老师个数和学生个数函数
void Person_TnumorSnum(Personptr Per,int n);
//统计男女人数函数
void Person_MnumorWnum(Personptr Per,int n);
//人员信息输出函数
void Person_Output(Personptr Per,int n);
//堆区空间释放函数
Personptr Person_List_Free(Personptr Per);
#endif
//Person.c
#include "Person.h"
//堆区空间申请函数
Personptr Person_List_Found()
{
Personptr Per=(Personptr)malloc(sizeof(Person)*5);
if(Per==NULL)
{
puts("申请失败!");
return NULL;
}
puts("申请成功!");
return Per;
}
//人员信息输入函数
void Person_Input(Personptr Per,int n)
{
putchar(10);
printf("请输入人员信息:\n");
for(int i=0;i<n;i++)
{
printf("请输入姓名:");
scanf(" %s",Per[i].name);
printf("请输入性别:");
scanf(" %s",Per[i].sex);
printf("请输入职业:");
scanf(" %c",&Per[i].job);
if(Per[i].job=='s'||Per[i].job=='S')
{
printf("请输入分数:");
scanf(" %f",&Per[i].diff.score);
}
else if(Per[i].job=='t'||Per[i].job=='T')
{
printf("请输入职务:");
scanf(" %s",Per[i].diff.position);
}
}
puts("输入成功!");
}
//统计老师个数和学生个数函数
void Person_TnumorSnum(Personptr Per,int n)
{
int Tnum=0,Snum=0;
for(int i=0;i<n;i++)
{
if(Per[i].job=='s'||Per[i].job=='S')
Snum++;
else if(Per[i].job=='t'||Per[i].job=='T')
Tnum++;
}
putchar(10);
puts("统计成功!");
printf("老师的人数为:%d\n",Tnum);
printf("学生的人数为:%d\n",Snum);
}
//统计男女人数函数
void Person_MnumorWnum(Personptr Per,int n)
{
int Mnum=0,Wnum=0;
for(int i=0;i<n;i++)
{
if(strcmp(Per[i].sex,"男"))
Mnum++;
else if(strcmp(Per[i].sex,"女"))
Wnum++;
}
putchar(10);
puts("统计成功!");
printf("男的人数为:%d\n",Mnum);
printf("女的人数为:%d\n",Wnum);
}
//人员信息输出函数
void Person_Output(Personptr Per,int n)
{
putchar(10);
puts("\t\t\t所有人员信息");
puts("\t\t\t教职工");
puts("\t姓名\t\t性别\t\t职务\n");
for(int i=0;i<n;i++)
{
if(Per[i].job=='t'||Per[i].job=='T')
printf("\t%s\t\t%s\t\t%s\n",Per[i].name,Per[i].sex,Per[i].diff.position);
}
putchar(10);
puts("\t\t\t学生");
puts("\t姓名\t\t性别\t\t分数\n");
for(int i=0;i<n;i++)
{
if(Per[i].job=='s'||Per[i].job=='S')
printf("\t%s\t\t%s\t\t%.2f\n",Per[i].name,Per[i].sex,Per[i].diff.score);
}
puts("输出成功!");
}
//堆区空间释放函数
Personptr Person_List_Free(Personptr Per)
{
free(Per);
Per=NULL;
puts("释放成功!");
return Per;
}
运行结果:
2.定义商品信息:商品名称,商品单价,商品购买个数,商品描述,循环输入购买的商品,按单价排序,输出商品信息,计算最贵的商品以及一共花了多少钱?
在create函数,请实现在堆区申请内存5个连续的内存
在input函数,请实现循环输入购买的商品
在bubble函数,请实现按单价排序
在Max函数,计算最贵的商品名称
在Money函数,计算共花了多少钱
在output函数,请实现输出
实现释放堆区内存
//main.c
#include "Goods.h"
int main(int argc, const char *argv[])
{
//堆区空间申请函数
Goodsptr Gptr=Goods_create();
//商品信息输入函数
Goods_Input(Gptr,5);
//单价排序函数
Goods_bubble(Gptr,5);
//计算最贵商品函数
Goods_Max(Gptr,5);
//计算一共花了多少钱
Goods_Money(Gptr,5);
//商品信息输出函数
Goods_Output(Gptr,5);
//堆区空间释放函数
Gptr=Goods_Free(Gptr);
return 0;
}
//Goods.h
#ifndef GOODS_H
#define GOODS_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
typedef struct Goods
{
char name[100];
float price;
int num;
char blurb[1000];
}Goods,*Goodsptr;
//堆区空间申请函数
Goodsptr Goods_create();
//商品信息输入函数
void Goods_Input(Goodsptr Gptr,int n);
//单价排序函数
void Goods_bubble(Goodsptr Gptr,int n);
//计算最贵商品函数
void Goods_Max(Goodsptr Gptr,int n);
//计算一共花了多少钱
void Goods_Money(Goodsptr Gptr,int n);
//商品信息输出函数
void Goods_Output(Goodsptr Gptr,int n);
//堆区空间释放函数
Goodsptr Goods_Free(Goodsptr Gptr);
#endif
#include "Goods.h"
//堆区空间申请函数
Goodsptr Goods_create()
{
Goodsptr Gptr=(Goodsptr)malloc(sizeof(Goods)*5);
if(Gptr==NULL)
{
puts("申请失败!");
return NULL;
}
puts("申请成功!");
return Gptr;
}
//商品信息输入函数
void Goods_Input(Goodsptr Gptr,int n)
{
putchar(10);
if(Gptr==NULL)
{
puts("输入失败!");
return ;
}
printf("请输商品信息:\n");
for(int i=0;i<n;i++)
{
printf("请输入商品名称:");
scanf(" %s",Gptr[i].name);
printf("请输入商品价格:");
scanf(" %f",&Gptr[i].price);
printf("请输入购买数量:");
scanf(" %d",&Gptr[i].num);
printf("请输入商品介绍:");
scanf(" %s",Gptr[i].blurb);
}
puts("输入成功!");
}
//单价排序函数
void Goods_bubble(Goodsptr Gptr,int n)
{
putchar(10);
if(Gptr==NULL)
{
puts("输入失败!");
return ;
}
Goods temp;
for(int i=0;i<n-1;i++)
for(int j=0;j<n-i-1;j++)
if(Gptr[j].price<Gptr[j+1].price)
{
temp=Gptr[j];
Gptr[j]=Gptr[j+1];
Gptr[j+1]=temp;
}
putchar(10);
puts("排序成功!");
}
//计算最贵商品函数
void Goods_Max(Goodsptr Gptr,int n)
{
putchar(10);
if(Gptr==NULL)
{
puts("排查失败!");
return ;
}
int Max_index=0;
for(int i=0;i<n;i++)
{
if(Gptr[Max_index].price<Gptr[i].price)
Max_index=i;
}
printf("最贵的商品是:%s\n",Gptr[Max_index].name);
}
//计算一共花了多少钱
void Goods_Money(Goodsptr Gptr,int n)
{
putchar(10);
if(Gptr==NULL)
{
puts("计算失败!");
return ;
}
float Money=0;
for(int i=0;i<n;i++)
{
Money=Money+Gptr[i].price*Gptr[i].num;
}
printf("一共花了%.2f钱。\n",Money);
}
//商品信息输出函数
void Goods_Output(Goodsptr Gptr,int n)
{
putchar(10);
puts("\t\t\t所有商品信息");
puts("\t商品名称\t价格\t购买数量\t商品简介\n");
for(int i=0;i<n;i++)
{
printf("\t%s\t\t%.2f\t\t%d\t%s\n",Gptr[i].name,Gptr[i].price,Gptr[i].num,Gptr[i].blurb);
}
puts("输出成功!");
}
//堆区空间释放函数
Goodsptr Goods_Free(Goodsptr Gptr)
{
free(Gptr);
Gptr=NULL;
puts("释放成功!");
return Gptr;
}
运行结果: