《1》结构体基础知识:
<1>结构体类型定义及结构体变量定义
<2>结构体变量的引用
<3>结构体变量指针
《2》结构体知识进阶
<1>结构体做函数参数
<2>结构体数组
<3>案例
从键盘获取数据,给结构体变量初始化,并且排序,打印结构体
《3》工程开发中,结构体应用常见的模型及典型的错误用法
<1>结构体嵌套一级指针
<2>结构体嵌套二级指针
<3>深拷贝与浅拷贝
<1>结构体类型定义及结构体变量定义
//结构体类型定义:固定大小空间的内存块
struct teacher
{
char name[62];//64
int age;//4
//在32位编译环境下,默认4字节对齐
}
void main()
{
//结构体变量的定义及初始化
struct teacher t1={"daiwen",22};
system("pause");
}
//在c编译环境下和.cpp环境下变量定义方法有所区别
struct teacher t1;//C语言需要加上struct关键字
teacher t2;//C++中则不必
<2>结构体变量的引用
struct teacher
{
char name[64];
int age;
}
struct teacher t1;
<3>结构体变量指针
struct teacher *p1=NULL;
p1->age=10;
<1>结构体做函数参数
#include
#include
#include
struct teacher
{
char name[64];//64
int age ; //4
};
//形参改变,对实参没有影响
//形参是函数在临时区开辟的空间,随着函数的结束,空间将跟着销毁
void copy01(struct teacher from,struct teacher to)//用结构体变量作形参
{
memcpy(&to, &from,sizeof(struct teacher));
}
//形参和实参指向同一块地址空间,通过形参来改变实参,这正是指针的精华所在
//采用结构体指针变量作形参
void copy02(struct teacher* from,struct teacher* to)
{
memcpy(to, from,sizeof(struct teacher));
}
void main()
{
struct teacher t1={"dddd",23};
struct teacher t2={"t2",24};
struct teacher *p=NULL;
//copy01(t1,t2);
copy02(&t1,&t2);
printf("%s",t2.name );
printf("%s",p->name );
system("pause");
}
<2>结构体数组
结构体类型是复杂的数据类型,结构体指针一出来就是一级指针
struct teacher tarray[10];
tarray[0].age=11;//.为成员操作符
<3>案例
从键盘获取数据,给结构体变量初始化,并且排序,打印结构体
#include
#include
#include
struct Teacher //结构体
{
char name[62];
int age;
};
int printarray(struct Teacher *array,int num)//打印函数
{
int i=0;
for(i=0;iprintf("%d ",array[i].age);
}
return 0;
}
int sortarray(struct Teacher *tarray,int num )//排序函数
{
int i=0,j=0;
struct Teacher tmp;
for(i=0;i//选择排序法
{
for(j=i+1;jif(tarray[i].agereturn 0;
}
int main()
{
int i=0;
struct Teacher tarray[10];
for(i=0;i<4;i++)
{
printf("请输入age:\n");
scanf("%d",&tarray[i].age);
}
printf("排序之前:\n");
printarray(tarray,4);
printf("\n排序之后 \n");
sortarray(tarray,4);
printarray(tarray,4);
return 0;
}
在工程开发中,切忌将同一块空间进行重复释放,或者对于动态开辟的空间未释放,造成程序中出现野指针现象
<0>动态开辟及手动销毁空间
#include
#include
#include
struct Teacher
{
char name[62];
int age;
};
int printarray(struct Teacher *array,int num)
{
int i=0;
for(i=0;iprintf("%d ",array[i].age);
}
return 0;
}
int sortarray(struct Teacher *tarray,int num )
{
int i=0,j=0;
struct Teacher tmp;
for(i=0;ifor(j=i+1;jif(tarray[i].agereturn 0;
}
struct Teacher * createarray(int count )//动态创建函数
{
int i=0;
struct Teacher *p1=(struct Teacher*)malloc(count*sizeof(struct Teacher));
if( p1 == NULL )
{
return NULL;
}
for(i=0;imemset(&p1[i],0,sizeof(struct Teacher));
}
return p1;
}
void myfree(struct Teacher *parray)//释放空间函数
{
if(parray!=NULL)
{
free(parray);
parray=NULL;
}
}
int main()
{
int i=0;
struct Teacher *parray=createarray(10);
for(i=0;i<4;i++)
{
printf("请输入age:\n");
scanf("%d",&parray[i].age);
}
printf("排序之前:\n");
printarray(parray,4);
printf("\n排序之后 \n");
sortarray(parray,4);
printarray(parray,4);
myfree(parray);//内存释放,避免内存泄露
return 0;
}
<1>结构体嵌套一级指针
在被调函数中分配内存,在主调函数中使用,指针做函数参数,相当于函数的输出端口
#include
#include
#include
struct Teacher
{
char name[64];
char* a_name;//结构体嵌套一级指针
int age;
};
int printarray(struct Teacher *array,int num)
{
int i=0;
for(i=0;iprintf("\n%d ",array[i].age);
printf("%s ",array[i].name);
printf("%s",array[i].a_name);
}
return 0;
}
int sortarray(struct Teacher *tarray,int num )
{
int i=0,j=0;
struct Teacher tmp;
for(i=0;ifor(j=i+1;jif(tarray[i].agereturn 0;
}
struct Teacher * createarray(int count )
{
int i=0;
struct Teacher *p1=(struct Teacher*)malloc(count*sizeof(struct Teacher));
if( p1 == NULL )
{
return NULL;
}
for(i=0;imemset(&p1[i],0,sizeof(struct Teacher));
p1[i].a_name=(char*)malloc(128*sizeof(char));//手动为一级指针所指向的内存开辟空间
memset(p1[i].a_name,0,128*sizeof(char));//初始化
}
return p1;
}
void myfree(struct Teacher *parray,int num)
{
int i;
if(parray ==NULL )
{
return ;
}
for(i=0;iif(parray[i].a_name!=NULL)
//释放指针所指向的内存空间,牢记指针变量和指针所指向的内存空间是两个不同的东西
{
free(parray[i].a_name);
}
//不能这样单独释放name[64];
//因为struct Teacher 是自定义大小的内存空间,不能部分释放
/*if(parray[i].name !=NULL)
{
free(parray[i].name);
}*/
}
if(parray!=NULL)
{
free(parray);
parray=NULL;//垃圾话语
}
}
int main()
{
int i=0;
struct Teacher *parray=createarray(4);
for(i=0;i<4;i++)
{
printf("请输入age:\n");
scanf("%d",&parray[i].age);
printf("请输入name:\n");
scanf("%s",parray[i].name);
printf("请输入a_name:\n");
scanf("%s",parray[i].a_name);
}
printf("排序之前:\n");
printarray(parray,4);
printf("\n排序之后 \n");
sortarray(parray,4);
printarray(parray,4);
myfree(parray,4);//内存释放,避免内存泄露
return 0;
}
<2>结构体嵌套二级指针
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
//两个结构体变量之间的copy行为
struct teacher
{
char name[64];//64
char *a_name; //4 //结构体里面套一级指针
int age ; //4
char ** stuname;//结构体里面套二级指针
};
int printtArray(struct teacher *pArray, int num)
{
int i = 0;
int j = 0;
for (i=0; iprintf("\n %d ", pArray[i].age);
printf("%s ", pArray[i].name);
printf("%s ", pArray[i].a_name);
for (j=0; j<3; j++)
{
char **p2 = pArray[i].stuname;
printf("%s ", p2[j]);
}
}
return 0;
}
int sorttArray(struct teacher *pArray, int num )
{
int i = 0, j = 0;
struct teacher tmp;
for (i=0; i<4; i++)
{
for (j=i+1; jif (pArray[i].age < pArray[j].age)
{
tmp = pArray[i];
pArray[i] = pArray[j];
pArray[j] = tmp;
}
}
}
return 0;
}
struct teacher* creatTArray(int count)
{
int i = 0;int j = 0;
struct teacher*p1 = (struct teacher *)malloc(count*sizeof(struct teacher ));
if (p1 == NULL)
{
return NULL;
}
for (i=0; imemset(&p1[i], 0, sizeof(struct teacher));
memset(p1+i, 0, sizeof(struct teacher));
p1[i].a_name = (char *)malloc(128*sizeof(char)) ;// char buf[128*4]
memset(p1[i].a_name , 0, 128*sizeof(char));
//p1[i].stuname = (char **)malloc(100);
{
char **p2 = (char **)malloc(3*sizeof(char *));//p2为局部变量
for (j=0; j<3; j++)
{
p2[j] =(char *) malloc(128*sizeof(char));//为p2所对应内存开辟动态空间
memset(p2[j] , 0, 128*sizeof(char));//初始化p2为0
}
p1[i].stuname = p2;//将p2挂在学生内存上
}
}
return p1;
}
void free2p(char **p ,int num)//释放p2空间函数
{
int i = 0; int j = 0;
for (i=0; iif (p[i] != NULL)
{
free(p[i] );
}
}
free(p);
}
void freeTArray(struct teacher* tArray, int num)
{
int i = 0;
if (tArray == NULL)
{
return ;
}
for (i=0; ichar *p = tArray[i].a_name; //为什么这里需要释放
if (p != NULL)
{
free(p);
}
//释放手工的二维内存
if (tArray[i].stuname != NULL)
{
free2p(tArray[i].stuname, 3);
}
}
if (tArray != NULL)
{
free(tArray);
tArray = NULL; //垃圾话语
}
}
void main()
{
int i = 0; int j = 0;
struct teacher *pArray = creatTArray(4);
if (pArray == NULL)
{
return ;
}
for (i=0; i<2; i++)
{
int tmp = 0;
char *p = pArray[i].a_name;
printf("\n请输入age: " );
scanf("%d", &(pArray[i].age) ) ;
printf("\n请输入名字: " );
scanf("%s", pArray[i].name);
printf("\n请输入别名: " );
scanf("%s", p);
for (j=0; j<3; j++)
{
char **p2 = pArray[i].stuname;
printf("\n请输入学生的名字");
scanf("%s", p2[j]);
}
}
printf("\n排序之前\n");
printtArray(pArray, 2 );
printf("\n排序之后\n");
sorttArray(pArray, 2 );
printtArray(pArray, 2 );
freeTArray(pArray, 2);
system("pause");
}
<3>深拷贝与浅拷贝
从键盘输入赋给t1,再将t1拷贝给t2;
浅拷贝:只是机械的将t1内存空间中的内容拷到t2中,若出现指针,拷贝后的指针则会与原指针指向同一块内存空间,编译器并不会单独为其开辟新的空间,从而会导致对一块空间的多次释放,野指针由此产生;
深拷贝:在函数中,为拷贝函数动态的开辟空间,不再是公用同一块内存,避免将同一块空间重复释放的问题出现;
#include
#include
#include
struct teacher
{
char name[64];//64
char *a_name; //4 //结构体里面套一级指针
int age ; //4
};
int printtArray(struct teacher *pArray, int num)
{
int i = 0;
int j = 0;
for (i=0; iprintf("\n %d ", pArray[i].age);
printf("%s ", pArray[i].name);
printf("%s ", pArray[i].a_name);
}
return 0;
}
struct teacher* creatTArray(int count)
{
int i = 0;int j = 0;
struct teacher*p1 = (struct teacher *)malloc(count*sizeof(struct teacher ));
if (p1 == NULL)
{
return NULL;
}
for (i=0; imemset(&p1[i], 0, sizeof(struct teacher));
p1[i].a_name = (char *)malloc(128*sizeof(char)) ;// char buf[128*4]
memset(p1[i].a_name , 0, 128*sizeof(char));
}
return p1;
}
void freeTArray(struct teacher* tArray, int num)
{
int i = 0;
if (tArray == NULL)
{
return ;
}
for (i=0; ichar *p = tArray[i].a_name; //为什么这里需要释放
if (p != NULL)
{
free(p);
}
if (tArray != NULL)
{
free(tArray);
tArray = NULL; //垃圾话语
}
}
}
void mycopy(struct teacher *from,struct teacher *to)
{
memcpy(to,from,sizeof(struct teacher));
to->a_name =(char *)malloc(128);
to->a_name =from->a_name ;
}
//void main()
//{
// struct teacher* t1=creatTArray(1);
// struct teacher* t2=creatTArray(1);
// printf("\n请输入age: " );
// t1->age=11;
//
// printf("\n请输入名字: " );
// strcpy(t1->name ,"t1111");
//
// printf("\n请输入别名: " );
// strcpy(t1->a_name ,"t333");
// //(*t2)=(*t1);//浅拷贝
// mycopy(&t1,&t2);
//
//
// system("pause");
//}
void main()
{
struct teacher t1;
struct teacher t2;
printf("\n请输入age: " );
t1.age=11;
t1.a_name =(char*)malloc(128);
strcpy(t1.a_name ,"t333");
//t2=t1;//浅拷贝
mycopy(&t1,&t2);//深拷贝要自己开辟空间
if(t1.a_name !=NULL)
{
free(t1.a_name);
}
if(t2.a_name !=NULL)
{
free(t2.a_name);
}
system("pause");
}