结构体赋值的三种方法:结构体的对齐方式以及结构体嵌套指针的使用方法
结构体赋值的三种方法:结构体的对齐方式以及结构体嵌套指针的使用方法举个例子:在这个例子中struct data的大小为8个字节。
结构体数组定义结构体数组的方法很简单,同定义结构体变量是一样的,只不过将变量改成数组。或者说同前面介绍的普通数组的定义是一模一样的,如:
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个字节。