【C】Re09 结构体
一、结构体 Struct
创建和基本使用
#include <stdio.h> #include <stdlib.h> #include <string.h> // 自定义数据类型 : 结构体 struct Person { int age; char id[18]; char name[20]; int gender; }; // 创建结构体数据类型 void createStructType ( ) { struct Person man = { 23, "363301199804023324", "tom", 1 }; // 访问结构体数据通过点 printf("man age -> %d\n", man.age); printf("man id -> %s\n", man.id); printf("man name -> %s\n", man.name); printf("man gender -> %d\n", man.gender); } // 方式二 声明结构体之后附加变量名称 struct Ac { int property1; char property2[18]; char property3[20]; int property4; } sss; // 再后面声明变量名称 void createStructType2() { sss.property1 = 12; // 不可以直接赋值 sss.property2 = "sdas"; strcpy(sss.property2, "sss"); } int main() { createStructType(); return 0; }
属性值的交换:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Struct { int property1; char property2[10]; double property3; }; // 赋值操作 void structAssignment() { struct Struct s1; struct Struct s2 = { 22, "张三", 22.55 }; // 赋值方式1 为s1 逐个赋值操作 s1.property1 = s2.property1; strcpy(s1.property2, s2.property2); s1.property3 = s2.property3; // 赋值方式2 允许操作整体赋值的方式 s1 = s2; // 赋值方式3 使用memcpy函数 memcpy(&s1, &s2, sizeof(struct Struct)); } // 属性值交换操作 void structPropertyChange() { struct Struct s1 = { 10, "李四", 100.23 }; struct Struct s2 = { 22, "张三", 22.55 }; int property1Temp = s1.property1; s1.property1 = s2.property1; s2.property1 = property1Temp; // char property2Temp[10] = s1.property2; char property2Temp[10]; strcpy(property2Temp, s1.property2); strcpy(s1.property2, s2.property2); strcpy(s2.property2, property2Temp); double property3Temp = s1.property3; s1.property3 = s2.property3; s2.property3 = property3Temp; // 结构体允许整体作为一个TEMP进行交换操作 struct Struct tempStruct; tempStruct = s1; s1 = s2; s2 = tempStruct; } int main() { structPropertyChange(); return 0; }
结构体数组:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Struct { int property1; char property2[10]; double property3; }; void structArray() { struct Struct structs[5] = { {1,"张三1", 23.23}, {2,"张三2", 23.23}, {3,"张三3", 23.23}, {4,"张三4", 23.23}, {5,"张三5", 23.23}, }; int size = sizeof(structs) / sizeof(struct Struct); for (int i = 0; i < size; ++i) { printf( "element%d p1 : %d p2 : %s, p3 : %.2f\n", i, structs[i].property1, structs[i].property2, structs[i].property3 ); } } int main() { structArray(); return 0; }
嵌套的结构体:
#include <stdio.h> #include <stdlib.h> #include <string.h> // 结构体嵌套 struct Student { char stuID[10]; char name[4]; }; struct Teacher { char teachID[5]; char name[4]; struct Student student; }; void structNesting() { // 嵌套结构体创建方式 struct Teacher li = { "133001", "李四", { "122001", "小明"} }; // 允许修饰括号进行赋值 struct Teacher jie = { "133002", "杰哥", "122001", "小明" }; // 调用 printf( "nestingStructs -> teacherID : %s, name : %s, stuID : %s, stuName : %s\n", li.teachID, li.name, li.student.stuID, li.student.name ); } int main() { structNesting(); return 0; }
二、结构体和指针
#include <stdio.h> #include <stdlib.h> #include <string.h> // 结构体与指针 struct Student { int id; char name[4]; double score; }; void structWithPointer () { struct Student student = { 1, "Tom", 98.5 }; struct Student * studentPointer = &student; // 结构体指针 // 使用指针调用结构体属性的方式 printf( "use studentPointer to get properties :\n id : %d, name : %s, score : %.2f\n", studentPointer -> id, studentPointer -> name, studentPointer -> score ); // 使用结构体属性的方式调用: printf( "use structVariable to get properties :\n id : %d, name : %s, score : %.2f\n", student.id, student.name, student.score ); // 使用解引用 == 结构体变量 printf( "use *studentPointer to get properties :\n id : %d, name : %s, score : %.2f\n", (*studentPointer).id, (*studentPointer).name, (*studentPointer).score ); // 使用解地址 == 结构体指针 printf( "use &student to get properties :\n id : %d, name : %s, score : %.2f\n", (&student) -> id, (&student) -> name, (&student) -> score ); } int main() { structWithPointer (); return 0; }
三、结构体与堆区
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Student { int id; char * name; int age; }; void test() { struct Student student = { 12003, "aaa", 23 }; printf("name -> %s\n", student.name); // student.name[0] = 'A'; 不允许这样操作,aaa是字符串常量,无法被修改 printf("name -> %s\n", student.name); } void test2() { struct Student student = { 12003, NULL, 23 }; student.name = malloc(sizeof(char) * 64); // 结构体属性值创建在malloc堆区中 strcpy(student.name, "Jerry"); printf("name -> %s\n", student.name); strcpy(student.name, "Tom"); printf("name -> %s\n", student.name); } void customFree(void * pointer) { if (pointer != NULL) { free(pointer); pointer = NULL; } } void test3() { // 结构体本身和属性成员都在堆区中创建 struct Student * studentPointer = NULL; studentPointer = malloc(sizeof(struct Student)); studentPointer -> id = 1002001; studentPointer -> name = "Ach"; studentPointer -> age = 22; printf("id - %d, name - %s, age - %d\n", studentPointer->id, studentPointer->name, studentPointer->age); customFree(&studentPointer->id); customFree(studentPointer->name); customFree(&studentPointer->age); printf("id - %d, name - %s, age - %d\n", studentPointer->id, studentPointer->name, studentPointer->age); } int main() { test3(); return 0; }
四、Const与结构体:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Student { int id; char * name; int age; }; void sss() { struct Student s1 = { 100, "Tom", 18 }; struct Student const * p1 = &s1; // 常量指针,指针指向的内存空间不可以改变存储值,但是改变指向 struct Student * const p2 = &s1; // 指针常量,指向不可以改变,但是可以改变指向的内存空间存储值 struct Student const * const p3 = &s1; // 常量锁定,不可以操作任何的写入了 } int main() { sss(); return 0; }