结构体
结构体中 只要遇到 字符串的 就用 strcpy 进行操作不用 = 因为等号是进行的浅拷贝 只是将地址进行复制而不是复制对象本身
1 作用
> 结构体是一种构造类型的数据结构,
是一种或多种基本类型或构造类型的数据的集合
2 定义结构体
语法1
struct 结构体名 { // 定义变量 };
语法2:
定义结构体时顺带创建一个结构体变量
struct 结构体名 { // 定义变量 }结构体变量名;
语法3:
给结构体起别名
typedef struct 结构体名称 { // 定义成员变量 // 可以定义无数个成员变量 }别名;
语法4:
struct{ // 定义成员变量 // 可以定义无数个成员变量 } 结构体变量名;
3 创建结构体变量
语法1:
struct 结构体名称 结构体变量 = {值1,值2,值3,....}; struct 结构体名称 结构体变量;
语法2:
> 别名 结构体变量 = {值1,值2,值3,....}; > 别名 结构体变量;
注意:
# 结构体对象清0 # memset(&结构体变量名,0,sizeof(struct 结构体名称)); 结构体初始化 必须按照成员顺序和成员自身类型
4 结构体变量使用其中成员变量
存值
结构体变量.成员变量名 = 值;
注意:字符串的成员变量需要使用strcpy实现深拷贝
取值
结构体变量.成员变量名
5 计算结构体大小
> 对齐方式,默认按照最大的进行对齐 数组,结构体将被拆分为存储的数据的大小
示例:
struct Stu { short x; // 4 int a; // 4 char c; // 4 char str[50]; // 47 / 4 = 11 .. 3 = 12 * 4 = 48 };
6 强制对其
作用
默认的结构体的对齐方式是由其中最大的成员进行对齐的 使用强制对齐就会使用强制的大小进行对齐
语法
#pragma pack (value)时的指定对齐值value为1 2 4 8等
示例
#include <stdio.h> #pragma pack(2) struct Test { int x; // 4 int *p; // 8 char c; // 2 short s; // 2 }; int main(int argc, char const *argv[]) { printf("%d\n", sizeof(struct Test)); return 0; }
特殊结构体
匿名结构体
特点
> 只能创建一个结构体变量
语法:
struct { 成员变量; }结构体变量名;
示例
#include <stdio.h> #include <string.h> struct { int age; char color[30]; }ql; int main(int argc, char const *argv[]) { ql.age = 8000; strcpy(ql.color,"黑"); printf("年龄:%d\t颜色:%s\n",ql.age,ql.color); return 0; }
整体赋值
> 结构体变量名1 = 结构体变量名2;
> 将结构体变量2的成员的值逐一赋值给结构体变量1的成员
memcpy****函数
作用:拷贝内存中的内容
语法
void *memcpy(void *dest, const void *src, size_t n); 参数: dest:目标地址 src:资源地址 n:长度
结构体定义结构体变量
概念: 结构体A中的成员变量是结构体B的变量
示例:
#include <stdio.h> typedef struct dog { char name[50]; char sex[10]; int age; } Dog; typedef struct person { char name[50]; char sex[10]; int age; // 结构体中定义结构体变量 Dog dog; } Person; int main(int argc, char const *argv[]) { Dog dog = {"旺财", "公", 3}; // 将上面定义的结构体变量dog全赋值给p1中的成员变量dog Person p1 = {"来福", "男", 18, dog}; dog.age = 13; printf("p1的姓名:%s\n", p1.name); printf("p1的性别:%s\n", p1.sex); printf("p1的年龄:%d\n", p1.age); printf("p1 dog的姓名:%s\n", p1.dog.name); printf("p1 dog的性别:%s\n", p1.dog.sex); printf("p1 dog的年龄:%d\n", p1.dog.age); printf("dog的姓名:%s\n", dog.name); printf("dog的性别:%s\n", dog.sex); printf("dog的年龄:%d\n", dog.age); Person p2 = {"常威", "男", 28, {"黑豹", "母", 4}}; printf("p2的姓名:%s\n", p2.name); printf("p2的性别:%s\n", p2.sex); printf("p2的年龄:%d\n", p2.age); printf("p2 dog的姓名:%s\n", p2.dog.name); printf("p2 dog的性别:%s\n", p2.dog.sex); printf("p2 dog的年龄:%d\n", p2.dog.age); return 0; }
计算结构体大小
成员变量是结构体其占据的大小也是参与计算对齐单行大小的依据
如
#include <stdio.h> typedef struct Data1 { char c; // 1 int a; // 4 8 long b; // 8 } D1; // 16 typedef struct Data2 { char c; // 1 int i; // 4 short s; // 2 16 D1 d1; // 16 } D2; // 16+16 = 32 int main(int argc, char const *argv[]) { printf("%d\n", sizeof(D2)); return 0; }
结构体指针
概念
指向结构体变量的指针。
语法:
> 结构体名称 *指针变量名;
操作成员变量
指针变量名->成员变量名 指针变量名->成员变量名 = 值; 注意: 字符数组型需要使用strcpy
示例
#include <stdio.h> typedef struct stu { char name[50]; // 48 char sex[10]; // 12 int age; // 4 } Stu; void chang01(Stu s) { s.age = 29; } void chang02(Stu *s) { s->age = 29; } int main(int argc, char const *argv[]) { Stu s01 = {"张三", "男", 18}; Stu *p = &s01; printf("%s\n", p->name); p->age = 19; printf("%d\n", p->age); printf("%d\n", s01.age); // chang01(s01);//全赋值 chang02(&s01); // 传递的是地址 printf("%d\n", s01.age); return 0; }
指针作为结构体成员
示例1
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct stu { char *name; char *sex; int age; } Stu; int main(int argc, char const *argv[]) { char str01[] = "Tom"; char str02[] = "man"; // Stu s = {str01,str02,19}; // printf("s name = %s\n",s.name); // s.name[0] = 't'; // printf("str01 = %s\n",str01); // printf("s name = %s\n",s.name); // 成员变量位指针变量如何实现深拷贝 Stu s02; s02.name = calloc(50, 1); strcpy(s02.name, str01); s02.sex = calloc(10, 1); strcpy(s02.sex, str02); s02.age = 18; printf("s02 name = %s\n", s02.name); s02.name[0] = 't'; printf("str01 = %s\n", str01); printf("s name = %s\n", s02.name); free(s02.name); free(s02.sex); return 0; }
示例2
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct stu { char *name; char *sex; int age; } Stu; int main(int argc, char const *argv[]) { Stu *s01 = (Stu *)malloc(sizeof(Stu)); s01->name = (char *)malloc(50); s01->sex = (char *)malloc(10); memset(s01, 0, sizeof(Stu)); memset(s01->name, 0, 50); memset(s01->sex, 0, 10); strcpy(s01->name, "张三"); strcpy(s01->sex, "男"); s01->age = 20; printf("姓名:%s\t性别:%s\t年龄:%d\n", s01->name, s01->sex, s01->age); // 如果成员变量是指针,并且是动态开辟内存 // 此时如果直接释放该结构体变量会导致内存泄漏 // 所以应该先释放里面的成员变量的动态内存,在释放结构体变量的动态内存 free(s01->name); free(s01->sex); free(s01); return 0; }
示例3
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct dog { char *name; char *sex; int age; } Dog; typedef struct person { char *name; char *sex; int age; Dog *dog; } Person; int main(int argc, char const *argv[]) { Dog *d = (Dog *)calloc(1, sizeof(Dog)); // int d = 1; d->name = (char *)calloc(50, 1); d->sex = (char *)calloc(10, 1); Person *p = (Person *)calloc(1, sizeof(Person)); p->name = (char *)calloc(50, 1); p->sex = (char *)calloc(10, 1); p->dog = d; // p->dog = d Person *p2 = (Person *)calloc(1, sizeof(Person)); p2->name = (char *)calloc(50, 1); p2->sex = (char *)calloc(10, 1); p2->dog = d; free(d->name); free(d->sex); free(d); free(p->name); free(p->sex); free(p); free(p2->name); free(p2->sex); free(p2); return 0; }
数组存储结构体变量
示例1
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct dog { char name[50]; char sex[10]; int age; } Dog; int main(int argc, char const *argv[]) { Dog d01 = {"旺财01", "公", 2}; Dog d02 = {"旺财02", "公", 2}; Dog d03 = {"旺财03", "公", 2}; Dog ds[] = {d01, d02, d03}; int len = sizeof(ds) / sizeof(ds[0]); for (int i = 0; i < len; i++) { printf("姓名:%s\t性别:%s\t年 龄:%d\n",ds[i].name,ds[i].sex,ds[i].age); } return 0; }
示例2
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct dog { char name[50]; char sex[10]; int age; } Dog; int main(int argc, char const *argv[]) { Dog d01 = {"旺财01", "公", 2}; Dog d02 = {"旺财02", "公", 2}; Dog d03 = {"旺财03", "公", 2}; Dog *ds[] = {&d01, &d02, &d03}; int len = sizeof(ds) / sizeof(ds[0]); for (int i = 0; i < len; i++) { printf("姓名:%s\t性别:%s\t年龄:%d\n", ds[i]->name, ds[i] - > sex, ds[i]->age); } return 0; }
示例3
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct dog { char name[50]; char sex[10]; int age; } Dog; int main(int argc, char const *argv[]) { Dog *d01 = (Dog *)calloc(1, sizeof(Dog)); strcpy(d01->name, "旺财01"); strcpy(d01->sex, "公"); d01->age = 2; Dog *d02 = (Dog *)calloc(1, sizeof(Dog)); strcpy(d02->name, "旺财02"); strcpy(d02->sex, "公"); d02->age = 2; Dog *d03 = (Dog *)calloc(1, sizeof(Dog)); strcpy(d03->name, "旺财03"); strcpy(d03->sex, "公"); d03->age = 2; Dog *ds[] = {d01, d02, d03}; Dog **dss = &ds; for (int i = 0; i < 3; i++) { printf("姓名:%s\t性别:%s\t年龄:%d\n", dss[i]->name, dss[i] - > sex, dss[i]->age); free(dss[i]); } return 0; }
示例4
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct dog { char name[50]; char sex[10]; int age; } Dog; Dog **getDogs() { static Dog *dogs[10] = {0}; for (int i = 0; i < 10; i++) { char name[30] = "旺财"; sprintf(name, "旺财%d", i + 1); dogs[i] = (Dog *)calloc(1, sizeof(Dog)); strcpy(dogs[i]->name, name); strcpy(dogs[i]->sex, "公"); dogs[i]->age = 2; } return &dogs; } int main(int argc, char const *argv[]) { Dog **dogs = getDogs(); for (int i = 0; i < 10; i++) { printf("姓名:%s\n", dogs[i]->name); } return 0; }
示例5
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct dog { char name[50]; char sex[10]; int age; } Dog; Dog **getDogs() { Dog **dogs = (Dog **)calloc(10, sizeof(Dog *)); for (int i = 0; i < 10; i++) { Dog *d = (Dog *)calloc(1, sizeof(Dog)); char n[30] = {0}; sprintf(n, "旺财%d", i + 1); strcpy(d->name, n); printf("d = %p\n", d); dogs[i] = d; } return dogs; } int main(int argc, char const *argv[]) { Dog **dogs = getDogs(); for (int i = 0; i < 10; i++) { printf("姓名:%s\n", dogs[i]->name); } for (int i = 0; i < 10; i++) { free(dogs[i]); } free(dogs); return 0; }