1.结构体的定义和结构体变量
第一种方法:
//定义一个结构体
struct Teacher
{
char name[50];
int age;
};
void main()
{
struct Teacher t1;//定义一个结构体变量
system("pause");
}
//定义一个结构体的同时去定义变量
struct Teacher
{
char name[50];
int age;
}t1,t2;
void main()
{
t1.age = 36;
system("pause");
}
第三种方法:、//定义一个匿名结构体的同时去定义变量
struct
{
char name[50];
int age;
}t1,t2;
void main()
{
t1.age = 36;
system("pause");
}
第四种:定义结构体数据类型 ,定义变量
//定义一个结构体数据类型,下面的teacher就是一个数据类型
typedef struct Teacher
{
char name[50];
int age;
}teacher;
void main()
{
teacher t1;
system("pause");
}
2.初始化结构体和操作结构体
void main()
{
teacher t1 = {"luck",34};
system("pause");
}
这是一种,只要才变量名的后面跟大括号初始化就可以了,例如上面定义结构体和变量的同时去初始化,匿名的在变量名的后面初始化也是可以得。typedef struct Teacher
{
char name[50];
int age;
}teacher;
void main()
{
teacher t1 = {"luck",34};
//结构体的引用,操作
t1.age = 20;
strcpy(t1.name,"lilei");
//也可以通过指针操作
teacher* t = NULL;
t = &t1;
t->age = 50;
strcpy(t->name, "lucher");
printf("%d---%s",t->age,t->name);
system("pause");
}
3.结构体做函数参数
结构做函数参数的话,传递是不成功的,而是对结构体的拷贝形式处理。
必须通过结构体指针去传递。
typedef struct Teacher
{
char name[50];
int age;
}teacher;
void copyTeacher(teacher * to, teacher* from)
{
*to = *from;
}
void main()
{
teacher t1 = {"luck",34};
teacher t2;
copyTeacher(&t2,&t1);//从t1拷贝到t2中。
system("pause");
}
看一个小例子:动态申请和释放内存,创建要给老师结构体数组,根据输入老师的年龄排序和输出。//定义一个结构体数据类型,下面的teacher就是一个数据类型
typedef struct Teacher
{
char name[50];
int age;
}Teacher;
void createMalloc(Teacher** to,int num)
{
Teacher* tmp = NULL;
tmp =(Teacher*)malloc(sizeof(Teacher)*num);
*to = tmp;
}
void paixu(Teacher * t, int num)
{
if (t==NULL)
{
return;
}
int i, j;
Teacher tmp;
for (i = 0; i < num;i++)
{
for (j = i; i < num; i++)
{
if (t[i].age>t[j].age)
{
tmp = t[i];
t[i] = t[j];
t[j] = tmp;
}
}
}
}
void freemolloc(Teacher** ts)
{
free(*ts);
*ts = NULL;
}
void main()
{
Teacher* ts = NULL;
int num = 3;
createMalloc(&ts,num);
for (size_t i = 0; i < num; i++)
{
printf("请输入老师的年龄:");
scanf("%d",(*(ts+i)).age);
}
paixu(ts,num);
for (size_t i = 0; i < num; i++)
{
printf("老师年龄 %d",ts[i].age);
}
freemolloc(&ts);
system("pause");
}
4.在结构体中套入一级指针
当时使用一级指针的时候需要给分配内存和使用结束的时候释放内存。这里使用的是结构体数组,所以需要给每个元素分配内存,同时释放也是给每个元素释放内存的。
typedef struct Teacher
{
char name[50];
char * biename;
int age;
}Teacher;
void createMalloc(Teacher** to,int num)
{
Teacher* tmp = NULL;
tmp =(Teacher*)malloc(sizeof(Teacher)*num);
for (int i = 0; i < num;i++)
{
//(*(tmp + i)).biename = (char*)malloc(60);
tmp[i].biename = (char*)malloc(60);
}
*to = tmp;
}
void freemolloc(Teacher** ts,int num)
{
if (ts==NULL)
{
return;
}
for (int i = 0; i < num; i++)
{
free((*ts)[i].biename);
(*ts)[i].biename = NULL;
}
free(*ts);
*ts = NULL;
}
5.结构体中套二级指针(比较难)
情景每个老师下面带三个学生,分配三个学生的名字内存
typedef struct Teacher
{
char name[50];
char * biename;
char** stuname;
int age;
}Teacher;
void createMalloc(Teacher** to,int num)
{
Teacher* tmp = NULL;
tmp =(Teacher*)malloc(sizeof(Teacher)*num);
for (int i = 0; i < num;i++)
{
//(*(tmp + i)).biename = (char*)malloc(60);
tmp[i].biename = (char*)malloc(60);
tmp[i].stuname = (char**)malloc(sizeof(char*)*3);
for (int j = 0; j < 3;j++)
{
tmp[i].stuname[j] = (char*)malloc(30);
}
}
*to = tmp;
}
void freemolloc(Teacher** ts,int num)
{
if (ts==NULL)
{
return;
}
for (int i = 0; i < num; i++)
{
free((*ts)[i].biename);
(*ts)[i].biename = NULL;
for (size_t j = 0; j < num; j++)
{
char** sname=(*ts)[i].stuname;
if (sname[j]!=NULL)
{
free(sname[j]);
sname[j] = NULL;
}
}
}
free(*ts);
*ts = NULL;
}
6.结构体的深浅拷贝问题
这种事根据自己的项目实际情况做出的选择
#include <stdlib.h>
#include <stdio.h>
typedef struct Teacher {
int age;
char* name;
}Teacher;
void copyteacher(Teacher * to,Teacher* from)
{
//编译器的“=”只是浅拷贝,将from中的char* name的地址拷贝给了to中的char* name
//如果这个时候同时去释放t1和t2中的char* name的会报错的。
//所以要实行深拷贝 to申请内存,将from中的char* name 拷贝过去就ok了。
*to = *from;
(*to).name = (char*)malloc(30);
strcpy((*to).name,(*from).name);
}
void main()
{
Teacher t1 ;
Teacher t2;
t1.age = 26;
t1.name = (char*)malloc(30);
strcpy(t1.name,"lilei");
copyteacher(&t2, &t1);
printf("teacher1 %d---%s", t2.age, t2.name);
//printf("teacher2 %d---%s", t2.age, t2.name);
if(t1.name!=NULL)
{
free(t1.name);
t1.name = NULL;
}
if (t2.name != NULL)
{
free(t2.name);
t2.name = NULL;
}
system("pause");
}