C语言提高0——结构体是一种自定义数据类型
结构体数据类型
结构体变量
结构体指针
结构体数组
结构体作函数参数
结构体嵌套一级指针(未完全搞懂)
结构体嵌套二级指针(未学)
结构体中的深拷贝与浅拷贝
结构体中的偏移量
结构体
是一种构造数据类型,它把不同类型的数据组合成一个整体,来自定义数据类型
我们都知道在数据类型中,char类型占1个字节,short占2个字节,int占4个字节,long占8个字节等等。
在计算结构体大小时需要考虑其内存布局,结构体在内存中存放是按单元存放的,每个单元多大取决于结构体中最大基本类型的大小
https://www.cnblogs.com/kl2blog/p/6908048.html
一、结构体类型定义与结构体变量定义
1、常用的两种写法(定义类型,用类型去定义变量):
第一种:
//类型定义 struct teacher { char name[12]; int age; int id; }; void main() { //变量定义并初始化 struct teacher t1 = {"a",32,02}; }
第二种:用typedef
typedef struct teacher1 { char name[12]; int age; int id; }teacher1;
void main() { teacher1 t2 = {"a",32,02}; }
2、结构体变量定义与初始化的三种方法(了解其余两种)
第二种:定义类型的同时,定义变量(可以同时初始化,而且初始化只能在这里进行)
struct teacher { char name[12]; int age; int id; }t1,t2={“b”,23,02};
第三种:不带结构体名的
struct { char name[12]; int age; int id; }t1,t2={“b”,23,02};
3、操作结构体(内存空间)的两种方法
第一种:变量法 t1.
teacher1 t2 = {"a",32,02};
printf("%d\n", t2.age);
t2.age = 22;
printf("%d\n", t2.age);
t1..号是寻址操作 计算age 相对于 t1大变量的 偏移量 ===》计算 cup中进行。没有操作内存,=号才是操作内存。
第二种:指针法
teacher1* p = NULL; p = &t2; p->age = 12; printf("%d\n", p->age); strcpy(p->name, "t1name"); printf("t2.name:%s \n", p->name);
p-> 是寻址操作 算age 相对于 t2大变量的偏移量 ,计算 cup中进行。
二、结构体变量作函数参数 pk 结构体指针作函数参数(结构体内存四区模型)
1、=号操作下 编译器的行为
Teacher t1 = {"aaaa", 32, 02};
Teacher t2;
t2 = t1; //=号操作下 编译器的行为
//编译器给我们提供 简单 =号 赋值操作 。。。我们要顺从
printf("t2.name:%s \n", t2.name);
printf("t2.age:%d \n", t2.age);
printf("t2.id:%d \n", t2.id);
2、结构体变量作函数参数 pk 结构体指针作函数参数,到底哪个正确?
//结构体变量作函数参数 void copyTeacher(Teacher to, Teacher from ) { to = from; } //结构体指针作函数参数 void copyTeacher02(Teacher *to, Teacher *from ) { //(*to) = (*from); *to = *from; } void main() { Teacher t1 = {"aaaa", 32, 02}; Teacher t3; copyTeacher02(&t3, &t1); printf("t3.name:%s \n", t3.name); printf("t3.age:%d \n", t3.age); system("pause"); }
3、内存四区模型:

三、结构体作函数参数应用+结构体数组
1、定义一个结构体数组,输入年龄,排序
typedef struct teacher { char name[12]; int age; int id; }teacher; void printTeacher(teacher* array,int num) { int i; for (i = 0; i < num; i++) { printf("%d\n", array[i].age); } } void sortTeacher(teacher* array, int num) { int i, j; for (i = 0; i < num; i++) { for (j = 0; j < num - 1; j++) { if (array[j].age >array[j + 1].age) { teacher temp=array[j]; array[j] = array[j + 1]; array[j + 1] = temp; } } } } void main() { teacher tArray[3];//结构体数组 int i; for (i = 0; i < 3; i++) { printf("请输入三位老师年龄:"); scanf("%d", &tArray[i].age); } sortTeacher(tArray, 3); printTeacher(tArray, 3); system("pause"); }
2、在堆上开辟内存代替结构体数组
teacher* createTeacher(int num) { teacher* array = NULL; array=(teacher*)malloc(sizeof(teacher)*num); if (array==NULL) { return NULL; } return array; } void freeTeacher(teacher*p) { if (p != NULL) { free(p); } } void main() { int i; int num = 3; teacher* pArray = NULL; pArray = createTeacher(num); for (i = 0; i < 3; i++) { printf("请输入三位老师年龄:"); scanf("%d", &tArray[i].age); } sortTeacher(pArray, 3); printTeacher(pArray, 3); system("pause"); }
“free(p)”释放的是指针变量 p 所指向的内存,而不是指针变量 p 本身。指针变量 p 并没有被释放,仍然指向原来的存储空间。所以一定要记住一条:free(p) 完之后,一定要将指针变量 p 置为 NULL。
其实它就做了一件事:斩断指针变量与这块内存的关系。
https://www.cnblogs.com/chunzhulovefeiyue/p/6821317.html

四、结构体嵌套一级指针
注意的点:没有内存,哪来的指针!
typedef struct teacher { char name[12]; char* alisname;//定义了指针变量,但并没有指向内存空间 int age; int id; }teacher; void main() { printf("\nplease enter alisname:"); scanf("%d", (pArray[i].alisname));//向指针所指的内存空间copy数据 }
error!需要向指针赋值,让指针指向一块内存空间!malloc

teacher* createTeacher2(int num) { int i; teacher* array = NULL; array = (teacher*)malloc(sizeof(teacher)*num); memset(array, 0, sizeof(teacher)* num);//初始化内存 if (array == NULL) { return NULL; } for (i = 0; i < num; i++) { array[i].alisname = (char*)malloc(60); } return array; } void FreeTeacher(teacher *p, int num) { int i = 0; if (p == NULL) { return; } for (i = 0; i<num; i++) { if (p[i].alisname != NULL) { free(p[i].alisname); } } free(p); } void main() { int i; int num = 3; teacher* pArray = NULL; //pArray = createTeacher(num); pArray = createTeacher2(num); for (i = 0; i<num; i++) { printf("\nplease enter alisname:"); scanf("%d", (pArray[i].alisname)); } for (i = 0; i < num; i++) { printf("%d\n", *(pArray[i].alisname)); } system("pause"); }
五、结构体中嵌套二级指针
六、结构体中的深拷贝与浅拷贝
问题出现在结构体中嵌套一个一级指针,然后把结构体变量1复制到变量2中,一级指针只会把地址复制,而不会重新申请一块内存
解决办法:手动申请内存,并将内存空间的值copy过去

typedef struct teacher { char name[12]; char* pname2; int age; }teacher; //编译器的=号操作,只会把指针变量的值,从from copy 到 to,但 //不会 把指针变量 所指 的 内存空间 给copy过去..//浅copy //结构体中套一个 1级指针 或 二级指针 //如果 想执行深copy,再显示的分配内存 void copyTeacher(teacher *to, teacher *from) { *to = *from; //以下两步是深拷贝内容:不添加该程序会卡死 to->pname2 = (char*)malloc(100); *(to->pname2) = *(from->pname2); } void main() { teacher t1, t2; strcpy(t1.name, "name1"); t1.pname2 = (char*)malloc(100);//先分配内存 strcpy(t1.pname2,"sss"); //t1 copy t2 copyTeacher(&t2, &t1); if (t1.pname2 != NULL) { free(t1.pname2); t1.pname2 = NULL; } if (t2.pname2 != NULL) { free(t2.pname2); t2.pname2 = NULL; } system("pause"); }
七、结构体中的偏移量
int offsize1 = (int)&(p->age) - (int)p; // & (t1.age) int offsize2 = (int )&(((AdvTeacher *)0)->age ); printf("offsize1:%d \n", offsize1); printf("offsize2:%d \n", offsize2);
浙公网安备 33010602011771号