diff --git a/README.md b/README.md index 9cf9f9f..28f80e1 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,5 @@ #### day10: 数组指针,函数与指针,动态内存申请 #### day11: 动态内存申请,内存泄漏,字符串处理函数 + +#### day12: 字符串处理函数,const,结构体 diff --git a/day12/a.out b/day12/a.out new file mode 100755 index 0000000..ef9f251 Binary files /dev/null and b/day12/a.out differ diff --git a/day12/d10.c b/day12/d10.c new file mode 100644 index 0000000..9806f3d --- /dev/null +++ b/day12/d10.c @@ -0,0 +1,42 @@ +#include +#include +#include + +struct LRC +{ + int lineNo; // 行号 + char show_time[10]; // 歌词时间 + char content[128]; // 歌词内容 +} line1, line2; // 第一行歌词,第二行歌词 + +#define slrc struct LRC // 定义别名 + +int main() +{ + // line1.content = "天青色等烟雨,而我在等你"; // 错误,不能这样赋值,因为 content 是数组,不能直接赋值 + // 正确写法是使用 strcpy 函数 + + line1.lineNo = 1; + // 使用 strcpy 函数,将内容复制到结构体变量中成员的数组空间中 + strcpy(line1.show_time, "00:00:01"); + strcpy(line1.content, "天青色等烟雨,而我在等你"); + line2.lineNo = 2; + // 使用 strcat 也能达成同样的效果 + strcat(line2.show_time, "00:00:06"); + strcat(line2.content, "炊烟袅袅升起,隔江千万里"); + + printf("%d %s %s\n", line1.lineNo, line1.show_time, line1.content); + printf("%d %s %s\n", line2.lineNo, line2.show_time, line2.content); + + // 创建第三行 + slrc line3 = {.lineNo = 3, .show_time = "00:00:11", .content = "在瓶底书汉隶仿前朝的飘逸"}; + printf("%d %s %s\n", line3.lineNo, line3.show_time, line3.content); + + slrc line4 = line3; // 结构体变量之间可以直接赋值 + line4.lineNo = 4; + // line4.content = "加个字"; // 错误,不能这样赋值,因为 content 是数组,不能直接赋值 + strcat(line4.content, "加个字"); + printf("%d %s %s\n", line4.lineNo, line4.show_time, line4.content); + + return 0; +} \ No newline at end of file diff --git a/day12/d10_2.c b/day12/d10_2.c new file mode 100644 index 0000000..c8c5455 --- /dev/null +++ b/day12/d10_2.c @@ -0,0 +1,16 @@ +#include +#include + +struct +{ + char name[20]; + float score; +} c1, c2, c3; + +int main() +{ + strcpy(c1.name, "张三"); + c1.score = 99.5f; + printf("姓名:%s 成绩:%.2f\n", c1.name, c1.score); + return 0; +} \ No newline at end of file diff --git a/day12/d11.c b/day12/d11.c new file mode 100644 index 0000000..8272412 --- /dev/null +++ b/day12/d11.c @@ -0,0 +1,25 @@ +// 定义结构体时指定新类型名 +#include +#include + +typedef struct lrc_s +{ + unsigned int num; // 时间 + char content[128]; // 歌词 +} LRC; // LRC 是新类型名 + +int main() +{ + struct lrc_s line1; + LRC line2 = { + .num = 2, + .content = "炊烟袅袅升起,隔江千万里"}; // LRC 是新类型名,可以直接使用 + + line1.num = 1; + strcpy(line1.content, "天青色等烟雨,而我在等你"); + + printf("%d %s\n", line1.num, line1.content); + printf("%d %s\n", line2.num, line2.content); + + return 0; +} \ No newline at end of file diff --git a/day12/d12.c b/day12/d12.c new file mode 100644 index 0000000..371c15c --- /dev/null +++ b/day12/d12.c @@ -0,0 +1,26 @@ +#include +#include + +typedef struct stu_s +{ + unsigned short sid; + // char name[32] = ""; // 不能在定义时初始化,因为结构体是类型,不是变量 + char name[32]; + unsigned short hight; + float weight; +} STU_INFO; + +int main() +{ + for (int i = 0; i < 3; i++) + { + // struct stu_s stu; // 重复定义,不会报错,但是不建议这么做 + STU_INFO stu; + printf("请输入学号 姓名 身高 体重:"); + // %hu 是 unsigned short 的格式化输出 + scanf("%hu %s %hu %f", &stu.sid, stu.name, &stu.hight, &stu.weight); + printf("第%d位-->学号:%hu 姓名:%s 身高:%hu 体重:%.2f\n", i + 1, stu.sid, stu.name, stu.hight, stu.weight); + } + + return 0; +} \ No newline at end of file diff --git a/day12/d13.c b/day12/d13.c new file mode 100644 index 0000000..a88b143 --- /dev/null +++ b/day12/d13.c @@ -0,0 +1,26 @@ +#include +#include + +typedef struct stu_s +{ + unsigned short sid; + char name[32]; + unsigned short hight; + float weight; +} STU_INFO; + +int main() +{ + STU_INFO stu; + for (int i = 0; i < 3; i++) + { + // 结构体清空数据 + memset(&stu, 0, sizeof(STU_INFO)); // 清空结构体 + printf("请输入学号 姓名 身高 体重:"); + // %h 是短整型,%u 是无符号整型 + scanf("%hu %s %hu %f", &stu.sid, stu.name, &stu.hight, &stu.weight); + printf("第%d位-->学号:%hu 姓名:%s 身高:%hu 体重:%.2f\n", i + 1, stu.sid, stu.name, stu.hight, stu.weight); + } + + return 0; +} \ No newline at end of file diff --git a/day12/d14.c b/day12/d14.c new file mode 100644 index 0000000..a9683e8 --- /dev/null +++ b/day12/d14.c @@ -0,0 +1,25 @@ +// 结构体的成员是指针 +// 如果结构体中的成员是指针时,可以直接赋值(常量区的地址)或者可以从堆区申请空间后赋值 + +#include +#include + +struct Data1 +{ + int n; + char *name; +}; + +int main() +{ + struct Data1 d1 = {1, "lucy"}; + printf("%d %s\n", d1.n, d1.name); + + struct Data1 d2; + d2.n = 100; + // 字符数组名不能直接赋值,只能使用 strcpy 函数,因为数组名是常量 + d2.name = "jack"; // 指针变量可以指向其它内容,可以修改 + printf("%d %s\n", d2.n, d2.name); + + return 0; +} \ No newline at end of file diff --git a/day12/d15.c b/day12/d15.c new file mode 100644 index 0000000..1e6bbcc --- /dev/null +++ b/day12/d15.c @@ -0,0 +1,27 @@ +// 结构体的成员是指针 +// 如果结构体中的成员是指针时,可以直接赋值(常量区的地址)或者可以从堆区申请空间后赋值 + +#include +#include + +struct Data1 +{ + int n; + char *name; +}; + +int main() +{ + struct Data1 d1 = {1, "lucy"}; + printf("%d %s\n", d1.n, d1.name); + + struct Data1 d2; + d2.n = 100; + d2.name = (char *)malloc(32); // 申请堆区空间 + // d2.name = "lucy"; // 导致内存泄漏,因为指针变量指向了常量区的地址,而不是堆区的地址 + strcpy(d2.name, "lucy"); // 修改堆区的内容 + printf("%d %s\n", d2.n, d2.name); + + free(d2.name); // 释放堆区空间,否则会导致内存泄漏 + return 0; +} \ No newline at end of file diff --git a/day12/d16.c b/day12/d16.c new file mode 100644 index 0000000..784c19f --- /dev/null +++ b/day12/d16.c @@ -0,0 +1,33 @@ +#include +#include + +struct lrc_time +{ + char hour; + char minute; + char second; +}; + +// 嵌套结构体,需要逐层赋值 +typedef struct lrc +{ + struct lrc_time start_time; // 开始时间 + char *content; +} LRC; + +int main() +{ + // 定义结构体变量并初始化值 + LRC line1 = {{0, 0, 2}, "天青色等烟雨,而我在等你"}; + + LRC line2; + line2.start_time.hour = 0; + line2.start_time.minute = 1; + line2.start_time.second = 15; + line2.content = "炊烟袅袅升起,隔江千万里"; + + printf("%02d:%02d:%02d %s\n", line1.start_time.hour, line1.start_time.minute, line1.start_time.second, line1.content); + printf("%02d:%02d:%02d %s\n", line2.start_time.hour, line2.start_time.minute, line2.start_time.second, line2.content); + + return 0; +} \ No newline at end of file diff --git a/day12/d17.c b/day12/d17.c new file mode 100644 index 0000000..dd4f2c9 --- /dev/null +++ b/day12/d17.c @@ -0,0 +1,20 @@ +#include +#include + +struct goods_s +{ + char name[30]; + float price; +}; + +int main() +{ + struct goods_s g1 = {"华为手机", 6500}; + struct goods_s g2 = g1; // 两个相同结构的变量可以直接赋值(浅拷贝: 复制第一层内存空间) + strcpy(g2.name, "华为平板"); + g2.price = 9000.0f; + printf("商品名称:%s 价格:%.2f\n", g1.name, g1.price); + printf("商品名称:%s 价格:%.2f\n", g2.name, g2.price); + + return 0; +} \ No newline at end of file diff --git a/day12/d18.c b/day12/d18.c new file mode 100644 index 0000000..f7afce0 --- /dev/null +++ b/day12/d18.c @@ -0,0 +1,44 @@ +#include +#include + +struct user_s +{ + int uid; + char *name; +}; + +struct goods_s +{ + int gid; + float price; + char *name; +}; + +struct order_s +{ + struct user_s user; + struct goods_s goods; + float order_price; // 订单总价 + int num; // 购买数量 + int pay_status; // 支付状态 0:未支付 1:已支付 2:取消支付 +}; + +int main() +{ + struct user_s user1 = {1, "disen"}; + struct user_s user2 = {2, "lucy"}; + struct goods_s goods1 = {201, 1200.0f, "华为手表"}; + struct goods_s goods2 = {202, 225000.0f, "华为汽车"}; + struct order_s order1 = { + user1, + goods1, 1200.0f, 1, 1}; + struct order_s order2 = order1; + // order2.user.name = "小李子"; + // order2.goods.name = "华为汽车"; + + order2.user = user2; + order2.goods = goods2; + + printf("order1 %s 购买 %s 订单状态: %d\n", order1.user.name, order1.goods.name, order1.pay_status); + printf("order2 %s 购买 %s 订单状态: %d\n", order2.user.name, order2.goods.name, order2.pay_status); +} diff --git a/day12/d19.c b/day12/d19.c new file mode 100644 index 0000000..44c5a63 --- /dev/null +++ b/day12/d19.c @@ -0,0 +1,37 @@ +#include +#include +#include // sqrt 函数 + +// 键盘输入 2 个点的坐标,计算两点之间的距离 (欧氏距离,勾股定理) +// 还有一种距离叫 曼哈顿距离,两点之间的距离是两点在坐标系上的横纵坐标的距离之和 +// 欧式距离公式: d = sqrt((x1-x2)^2 + (y1-y2)^2) +// 曼哈顿距离公式: d = |x1-x2| + |y1-y2| +// gps 的距离使用的是曼哈顿距离 + +// 定义结构体 +struct Point +{ + int x; + int y; +}; + +int main() +{ + struct Point twoPoint[2]; + memset(&twoPoint[0], 0, sizeof(twoPoint)); + memset(&twoPoint[1], 0, sizeof(twoPoint)); + + for (int i = 0; i < 2; i++) + { + printf("请输入第%d个点的坐标: ", i + 1); + scanf("%d %d", &twoPoint[i].x, &twoPoint[i].y); + } + + // 计算两点之间的距离 + // sqrt 函数在 math.h 头文件中 + // pow 函数在 math.h 头文件中,求幂函数,pow(x, y) 求 x 的 y 次方 + float d1 = sqrt(pow(twoPoint[0].x - twoPoint[1].x, 2) + pow(twoPoint[0].y - twoPoint[1].y, 2)); + printf("两点之间的距离是: %.2f\n", d1); + + return 0; +} \ No newline at end of file diff --git a/day12/d20.c b/day12/d20.c new file mode 100644 index 0000000..db741d6 --- /dev/null +++ b/day12/d20.c @@ -0,0 +1,23 @@ +#include +#include + +struct POS +{ + int x; + int y; +}; + +int main() +{ + struct POS p1 = {0, 0}; + struct POS *p2 = &p1; // 结构体指针指向结构体变量 + // p2.x = 2; // 错误,结构体指针不能直接访问结构体变量的成员,需要使用 -> 运算符 + p2->x = 2; + p2->y = 2; + + printf("point1 x=%d, y=%d\n", p1.x, p1.y); + printf("point2 x=%d, y=%d\n", p2->x, p2->y); + // printf("point2 x=%d, y=%d\n", (*p2).x, (*p2).y); // *p2 也是一个结构体变量,可以使用 . 运算符访问成员 + + return 0; +} \ No newline at end of file diff --git a/day12/d20_2.c b/day12/d20_2.c new file mode 100644 index 0000000..06aea3b --- /dev/null +++ b/day12/d20_2.c @@ -0,0 +1,24 @@ +#include +#include +#include + +// 结构体存在堆区,结构体的成员也存在堆区 +struct POS +{ + int *x; + int *y; +}; + +int main() +{ + struct POS *p1 = malloc(sizeof(struct POS)); + p1->x = (int *)malloc(sizeof(int)); + p1->y = (int *)malloc(sizeof(int)); + + *(p1->x) = 20; + *(p1->y) = 30; + + printf("point1 x=%d, y=%d\n", *(p1->x), *((*p1).y)); + + return 0; +} \ No newline at end of file diff --git a/day12/d21.c b/day12/d21.c new file mode 100644 index 0000000..6f053aa --- /dev/null +++ b/day12/d21.c @@ -0,0 +1,31 @@ +// 浅拷贝 +#include +#include +#include + +struct POS +{ + int *x; + int *y; +}; + +int main() +{ + struct POS *p1 = malloc(sizeof(struct POS)); + p1->x = (int *)malloc(sizeof(int)); + p1->y = (int *)malloc(sizeof(int)); + *(p1->x) = 20; + *(p1->y) = 30; + printf("point1 x=%d,y=%d\n", *(p1->x), *(p1->y)); + + struct POS *p2 = malloc(sizeof(struct POS)); + memcpy(p2, p1, sizeof(struct POS)); // 浅拷贝,只拷贝了结构体本身,没有拷贝结构体成员 + *(p2->x) = 200; + printf("point2 x=%d,y=%d\n", *(p2->x), *(p2->y)); + printf("point1 x=%d,y=%d\n", *(p1->x), *(p1->y)); + free(p1->x); + free(p1->y); + free(p1); + free(p2); + return 0; +} \ No newline at end of file diff --git a/day12/d9.c b/day12/d9.c new file mode 100644 index 0000000..e7cfd4b --- /dev/null +++ b/day12/d9.c @@ -0,0 +1,59 @@ +// 结构体,也是构造类型之一,由至少一个基本数据类型或构造类型组成的一种数据类型 +// 结构体的成员可以是基本数据类型或构造类型 +#include +#include + +/* + // 语法1: 只声明结构体 + struct 结构体类型的名称 + { + // 声明成员变量,成员变量不要初始化(值) + 成员类型1 成员名称1; + 成员类型2 成员名称2; + ... 成员类型n 成员名称n; + }; + + // 语法2: 声明结构体时,同时声明结构体类型的变量 + struct 结构体类型的名称 + { + // 声明成员变量,成员变量不要初始化(值) + 成员类型1 成员名称1; + 成员类型2 成员名称2; + ... 成员类型n 成员名称n; + } 结构体类型的变量1, 结构体类型的变量2, ... 结构体类型的变量n; + + // 语法3: 一次性声明结构体 + struct + { + // 声明成员变量 + + } 变量名; +*/ + +struct STU +{ + unsigned int sid; // 存放学号 + char name[32]; // 存放姓名 + char phone[12]; // 存放手机号,12个字节,11个数字,最后一个字节存放'\0' +}; + +#define sstu struct STU // 定义别名 + +int main() +{ + // 定义 STU 类型的变量,存放张三这个学生,学号为1001,手机号为17791692095 + // 结构体变量在初始化时,按成员的顺序和数据类型依次赋值 + sstu s1 = {1001, "张三", "17791692095"}; + sstu s3 = {1003, "王五", "17791692097"}; + // 存其他学生的信息 + struct STU s2; + s2.sid = 1002; + strcpy(s2.name, "李四"); + strcpy(s2.phone, "17791692096"); + + printf("sid: %u name: %s phone: %s\n", s1.sid, s1.name, s1.phone); + printf("sid: %u name: %s phone: %s\n", s2.sid, s2.name, s2.phone); + printf("sid: %u name: %s phone: %s\n", s3.sid, s3.name, s3.phone); + + return 0; +} \ No newline at end of file