结构体数组
定义结构体数组的方法很简单,同定义结构体变量是一样的,只不过将变量改成数组。或者说同前面介绍的普通数组的定义是一模一样的,如:
struct STUDENT stu[10];
这就定义了一个结构体数组,共有 10 个元素,每个元素都是一个结构体变量,都包含所有的结构体成员。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
typedef struct Teacher
{
char name[50];
//char* name;
int age;
}Teacher;
int main()
{
Teacher a[3] = {
{"a",11},
{"b",12},
{"c",13}
};
//静态
Teacher a2[3] = { "aa",13,"bb",12 ,"cc",13};
for (int i = 0; i < 3; i++)
{
printf("%s, %d\n", a2[i].name, a2[i].age);
}
int b[3] = { 0 };
int* pB = (int*)malloc(3 * sizeof(int));
free(pB);
//Teacher p[3]
Teacher* p = (Teacher*)malloc(3 * sizeof(Teacher));
if (p==NULL)
{
return -1;
}
char buf[50];
for (int i = 0; i < 3; i++)
{
sprintf(buf, "name%d%d%d", i, i, i);
strcpy(p[i].name, buf);
p[i].age = 20 + i;
}
for (int i = 0; i < 3; i++)
{
printf("第%d个:%s,%d\n", i + 1, p[i].name, p[i].age);
}
printf("\n");
if (p!=NULL)
{
free(p);
p = NULL;
}
return 0;
}
结构体嵌套一级指针
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
typedef struct Teacher
{
char* name;
int age;
}Teacher;
showTeacher(Teacher* q, int n)
{
for (int i = 0; i < n; i++)
{
printf("%s ,%d\n", q[i].name, q[i].age);
}
}
freeTeacher(Teacher* q, int n)
{
for (int i = 0; i < n; i++)
{
if (q[i].name != NULL)
{
free(q[i].name);
q[i].name = NULL;
}
}
if (q != NULL)
{
free(q);
q = NULL;
}
}
Teacher* getMem( int n)
{
Teacher*q = (Teacher*)malloc(sizeof(Teacher));
//Teacher q[3]
char buf[30];
for (int i = 0; i < n; i++)
{
q[i].name = (char*)malloc(30);
sprintf(buf, "name%d%d%d", i, i, i);
strcpy(q[i].name, buf);
q[i].age = 20 + i;
}
return q;
}
Teacher* getMem2(Teacher**temp,int n)
{
if (temp==NULL)
{
return -1;
}
Teacher* q = (Teacher*)malloc(sizeof(Teacher));
//Teacher q[3]
char buf[30];
for (int i = 0; i < n; i++)
{
q[i].name = (char*)malloc(30);
sprintf(buf, "name%d%d%d", i, i, i);
strcpy(q[i].name, buf);
q[i].age = 20 + i;
}
*temp = q;
return 0;
}
int main()
{
char* name = NULL;
name = (char*)malloc(30);
strcpy(name, "aa");
printf("name=%s\n", name);
if (name!=NULL)
{
free(name);
name = NULL;
}
//1
Teacher t;
t.name = (char*)malloc(30);
strcpy(t.name, "s");
t.age = 22;
printf("name=%s age=%d\n", t.name, t.age);
if (t.name!=NULL)
{
free(t.name);
t.name = NULL;
}
//2
Teacher* p = NULL;
p = (Teacher*)malloc(sizeof(Teacher));
p->name = (char*)malloc(30);
strcpy(p->name, "ss");
p->age = 22;
printf("name=%s age=%d\n", p->name, p->age);
if (p->name!=NULL)
{
free(p->name);
p->name = NULL;
}
if (p!=NULL)
{
free(p);
p = NULL;
}
//3
Teacher* q = NULL;
//q = getMem(3);
int ret = 0;
ret = getMem2(&q, 3);
if (ret!=NULL)
{
return ret;
}
showTeacher(q,3);
freeTeacher(q, 3);
p = NULL;
return 0;
}
结构体嵌套二级指针
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
//一个导师有若干学生
typedef struct Teacher
{
int age;
char**stu;//二维内存
}Teacher;
//n1老师个数 n2每个老师带的学生数
int createTeacher(Teacher** temp, int n1,int n2)
{
if (temp==NULL)
{
return -1;
}
Teacher* q = (Teacher*)malloc(sizeof(Teacher) * n1);
//Teacher q[3]
for (int i = 0; i < n1; i++)
{
//q[i].stu
//(q+i)->stu
q[i].stu = (char**)malloc(sizeof(char*)*n2);
//char* stu[3]
for (int j = 0; j < n2; j++)
{
q[i].stu[j] = (char*)malloc(30);
char buf[30];
sprintf(buf, "name%d%d%d%d", i, i, j, j);
strcpy(q[i].stu[j], buf);
}
q[i].age = 20 + i;
}
*temp = q;
return 0;
}
void showTeacher(Teacher* q, int n1, int n2)
{
if (q=NULL)
{
return;
}
for (int i = 0; i < n1; i++)
{
printf("[age=%d]\t", q[i].age);
for (int j = 0; j < n2; j++)
{
printf("%s, \n", q[i].stu[j]);
}
printf("\n");
}
printf("\n");
}
void sortTeacher(Teacher*p,int n)
{
if (p==NULL)
{
return;
}
Teacher temp;
for (int i = 0; i < n-1; i++)
{
for (int j = i+1; j < n; j++)
{
if (p[i].age < p[j].age)//降序
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
void freeTeacher(Teacher** temp, int n1, int n2)
{
if (temp==NULL)
{
return;
}
Teacher* q = *temp;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (q[i].stu[j] != NULL)
{
free(q[i].stu[j]);
q[i].stu[j] = NULL;
}
}
if (q[i].stu != NULL)
{
free(q[i].stu);
q[i].stu = NULL;
*temp = NULL;
}
}
if (q != NULL)
{
free(q);
q = NULL;
}
}
int main()
{
char** name = NULL;
//char* name[3]
int n = 3;
name = (char**)malloc(sizeof(char*) * 3);
for (int i = 0; i < n; i++)
{
name[i] = (char*)malloc(30);
strcpy(name[i], "aaa");
}
for (int i = 0; i < n; i++)
{
printf("%s\n", name[i]);
}
for (int i = 0; i < n; i++)
{
if (name[i]!=NULL)
{
free(name[i]);
name[i] = NULL;
}
}
if (name!=NULL)
{
free(name);
name = NULL;
}
//1
Teacher t;
//t.stu[3]
//char* t.stu[3]
int n = 3;
t.stu = (char**)malloc(sizeof(char*) * 3);
for (int i = 0; i < n; i++)
{
t.stu[i] = (char*)malloc(30);
strcpy(t.stu, "aaa");
}
for (int i = 0; i < n; i++)
{
printf("%s\n",t.stu[i]);
}
for (int i = 0; i < n; i++)
{
if (t.stu[i] != NULL)
{
free(t.stu[i]);
t.stu[i] = NULL;
}
}
if (t.stu != NULL)
{
free(t.stu);
t.stu = NULL;
}
//2
Teacher* p = NULL;
//p->stu[3]
p = (Teacher*)malloc(sizeof(Teacher));
//char* t.stu[3]
int n = 3;
p->stu = (char**)malloc(sizeof(char*) * 3);
for (int i = 0; i < n; i++)
{
p->stu[i] = (char*)malloc(30);
strcpy(p->stu, "aaa");
}
for (int i = 0; i < n; i++)
{
printf("%s\n", p->stu[i]);
}
for (int i = 0; i < n; i++)
{
if (p->stu[i] != NULL)
{
free(p->stu[i]);
p->stu[i] = NULL;
}
}
if (p->stu != NULL)
{
free(p->stu);
p->stu = NULL;
}
if (p!=NULL)
{
free(p);
p = NULL;
}
//3
Teacher* q = NULL;
int ret = 0;
ret = createTeacher(&q, 3,3);
//Teacher* q[3]
//q[i].stu[3]
printf("排序前\n");
showTeacher(q, 3, 3);
sortTeacher(q, 3);
printf("排序后\n");
showTeacher(q,3,3);
freeTeacher(&q, 3, 3);
return 0;
}
结构体的深拷贝与浅拷贝
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
typedef struct Teacher
{
char* name;
int age;
}Teacher;
//结构体中嵌套指针,而且动态分配空间
//同类型结构体变量赋值
//结构体成员指针变量指向同一块内存
int main()
{
Teacher t1;
t1.name = (char*)malloc(30);
strcpy(t1.name, "tom");
t1.age = 22;
Teacher t2;
t2 = t1;
//深拷贝,人为增加内容,重新拷贝一下
t2.name= (char*)malloc(30);
strcpy(t2.name, t1.name);
printf("[t2]%s,%d\n", t2.name, t2.age);
if (t1.name!=NULL)
{
free(t1.name);
t1.name = NULL;
}
//重复释放
//浅拷贝:t2的值还指向同一块内存 t1.name t1释放后t2又释放 导致出现错误
if (t2.name != NULL)
{
free(t2.name);
t2.name = NULL;
}
return 0;
}
结构体的对齐方式
结构体的对齐公式:
记住以下这些规则,把结构体往里面套就可以了。结构体对齐的原则就是牺牲空间的方式来减少时间的消耗,空间用完还可以复用,而时间过去了就再也不会回来了。
- 以 #pragma pack(x) 中 x 的大小和结构中占用空间最大的成员做比较,取小值为 n(外对齐依据)
- 以 n 值和结构体每个成员比较,得到结果列表为 m[x]
- 根据每个成员的大小依次向内存中填充数据,要求填充 成员的起始地址 减去 构体起始地址 的差都可以整除 m[x] ,如不能整除则向后移动,直到可以整除再填充成员到内存(内对齐依据)
- 当全部成员填充完毕后所占用的字节若不能整除 n,则扩充内存到可以整除 n 为止。
举个例子:

在这个例子中struct data的大小为8个字节。