13.结构体

/********************************************************************************************
* Module Name       :结构体
* Module versions:模块版本
* Module Date:2016/08/03
* Student:007
* Description       :说明书
* Others:合作其他人
* Revision History:修订历史
********************************************************************************************/

#define  _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define  STU_NUM   5



/*
结构体模版的定义
a、struct关键字
b、结构体名字:建议全大写
c、大括号将不同类型括起来
d、分号

内存分配:1、找出最大的类型作为基本单元
2、以基本单元为单位,逐步分配内存

float  4个字节,以4个字节为基本单元
iNum  1个基本单元
acName  5个基本单元
acSex   1个基本单元,多出一个字节
fScore  1个基本单元
一共8个基本单元  32个字节,其中31个字节是存储用的,1个字节是多余的
*/
typedef struct _STU
{
int iNum;
char acName[20];
char acSex[3];
float fScore;
}STU;

void PrintStuMsg(STU *ptStu, int iNum);
void InputStuMsg(STU *ptStu, int iNum);
STU *CheckStuMsg(STU *ptStu, int iNum);

int main()
{
/*
学号   姓名    性别   成绩
1      路飞老师  男    100
2      小鱼老师  女    99.5
3      贝熙老师  女    98
*/
/*
为了解决存储不同的类型的数据的情况,c语言提供了结构体来存储
结构体:将多种类型的数据打包成一个整体,这样的话,可以如同数组一样操作
3个部分:
1、结构体模板定义:模板一般是公用的,一般放在main前面(封装成c模块,就放在头文件)
2、定义结构体变量
3、引用结构体
*/
/*定义结构体变量
struct 结构体名  变量名(建议小写t开头)

&结构体名  结构体的首地址
*/
/*
给结构体赋值
初始化赋值:类似数组赋值
一个一个赋值

允许结构体拷贝

*/
STU tStu1 = { 1, "路飞老师", "男", 100 }, tStu2 = { 0 }, tStu3 = { 0 };
//结构体数组
STU tStu[STU_NUM] = { { 1, "路飞老师", "男", 100 },
{ 2, "小鱼老师", "女", 99 },
{ 3, "贝熙老师", "女", 98 },
{ 4, "小鱼老师", "女", 0 } };
//结构体指针
STU *ptStu = NULL;
int n = 256, *pi = NULL;

ptStu = &tStu1;
printf("指向结构体的指针\n");
PrintStuMsg(ptStu, 1);
//结构体引用
(*ptStu).iNum = 1;
//因为写法较为麻烦,所有提供另外一个符号,方便结构体指针引用->
ptStu->iNum = 1;

tStu1.iNum = 2;
strcpy(tStu1.acName, "小鱼老师");
strcpy(tStu1.acSex, "女");
tStu1.fScore = 99;
//拷贝:将结构体的内容全部拷贝到另外一个结构体中
tStu2 = tStu1;
printf("拷贝结构体\n");
PrintStuMsg(&tStu2, 1);

tStu2.iNum = 4;
tStu2.fScore = 0;
printf("拷贝结构体后修改\n");
PrintStuMsg(&tStu2, 1);
PrintStuMsg(&tStu1, 1);
/*
引用结构体变量,用点号
tStu.iNum
tStu.acName
tStu只是打包作用,实际要操作的对象还是包里面的变量
那么运算的时候,“只看”引用的包里面的变量
*/
pi = (int *)malloc(256 * sizeof(int));

ptStu = (STU *)malloc(STU_NUM * sizeof(STU));

InputStuMsg(ptStu, STU_NUM);
PrintStuMsg(ptStu, STU_NUM);

ptStu = CheckStuMsg(ptStu, 2);
//指针改变指向内容,原内容还存在,但是已经无法访问了,释放不了,一旦是子函数中,慢慢会将内存耗尽
PrintStuMsg(ptStu, 1);
free(ptStu);
free(pi);
/*
手动动态内存分配
数组  a[256] 前面的语法,定义的时候就必须限定死数组的大小
有没有方法在运行期间,根据需要分配相应大小的内存
int n;
scanf("%d",&n)
a[n]

char *pc="abc";

先分配大小为n的内存单元,然后将首地址给一个指针p
就等效于定义了一个数组p[n]

malloc(size)返回一个大小为size个字节的内存单元的首地址,可以通过指针获取
由于指针变量是有类型的,所以需要强制转换该首地址为相应的指针类型
p=(类型 *)malloc(size);

这种分配是静态,程序不结束不会释放,一般如果放在了子函数里面,那么每调用一次,都会分配掉
一定内存空间,最终耗尽内存空间

一般要求配对出现free(p);释放分配的空间
1、要么同一个函数段中配对出现
2、要么编写一个create和delete函数
*/

system("pause");
return 0;
}
/*=========================
* Function : PrintStuMsg
* Description   : 打印学生信息
* Input Para    :ptStu,学生信息
* Output Para   :ptStu,学生信息
* Return Value:无
===========================*/
void PrintStuMsg(STU *ptStu, int iNum)//(STU tStu)为了节省运行内存,可以使用指针,减少运行时间,提供效率
{
int i;
for (i = 0; i < iNum; i++)
{
if (ptStu != NULL)
{

printf("学号:%d;姓名:%s;性别:%s;分数:%f\n",
ptStu[i].iNum, ptStu[i].acName, ptStu[i].acSex, ptStu[i].fScore);
}
else
{
printf("不存在该学生信息\n");
}
}
}
/*=========================
* Function : InputStuMsg
* Description   : 输入学生信息
* Input Para    :ptStu,学生信息,iNum学生个数
* Output Para   :ptStu,学生信息
* Return Value:无
===========================*/
void InputStuMsg(STU *ptStu, int iNum)
{
int i;
for (i = 0; i < iNum; i++)
{
printf("****请输入第%d个学生的信息****\n", i + 1);
printf("请输入学号:");
scanf("%d", &ptStu[i].iNum);
printf("请输入姓名:");
scanf("%s", ptStu[i].acName);
printf("请输入性别:");
scanf("%s", ptStu[i].acSex);
printf("请输入分数:");
scanf("%f", &ptStu[i].fScore);
}
}
/*=========================
* Function : CheckStuMsg
* Description   : 查询某学号的学生信息
* Input Para    :所有的学生,查询的学号
* Output Para   :ptStu,学生信息
* Return Value:该学生信息内容
===========================*/
STU *CheckStuMsg(STU *ptStu, int iNum)
{
int i;
for (i = 0; i < STU_NUM; i++)
{
if (ptStu[i].iNum == iNum)
{
return &ptStu[i];
}
}
return NULL;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值