day12: 字符串处理函数,const,结构体

This commit is contained in:
flykhan 2023-07-18 19:06:37 +08:00
parent b75f87d375
commit 4e33e8f104
17 changed files with 460 additions and 0 deletions

View File

@ -15,3 +15,5 @@
#### day10: 数组指针,函数与指针,动态内存申请
#### day11: 动态内存申请,内存泄漏,字符串处理函数
#### day12: 字符串处理函数const结构体

BIN
day12/a.out Executable file

Binary file not shown.

42
day12/d10.c Normal file
View File

@ -0,0 +1,42 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;
}

16
day12/d10_2.c Normal file
View File

@ -0,0 +1,16 @@
#include <stdio.h>
#include <string.h>
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;
}

25
day12/d11.c Normal file
View File

@ -0,0 +1,25 @@
// 定义结构体时指定新类型名
#include <stdio.h>
#include <string.h>
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;
}

26
day12/d12.c Normal file
View File

@ -0,0 +1,26 @@
#include <stdio.h>
#include <string.h>
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;
}

26
day12/d13.c Normal file
View File

@ -0,0 +1,26 @@
#include <stdio.h>
#include <string.h>
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;
}

25
day12/d14.c Normal file
View File

@ -0,0 +1,25 @@
// 结构体的成员是指针
// 如果结构体中的成员是指针时,可以直接赋值(常量区的地址)或者可以从堆区申请空间后赋值
#include <stdio.h>
#include <string.h>
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;
}

27
day12/d15.c Normal file
View File

@ -0,0 +1,27 @@
// 结构体的成员是指针
// 如果结构体中的成员是指针时,可以直接赋值(常量区的地址)或者可以从堆区申请空间后赋值
#include <stdio.h>
#include <string.h>
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;
}

33
day12/d16.c Normal file
View File

@ -0,0 +1,33 @@
#include <stdio.h>
#include <string.h>
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;
}

20
day12/d17.c Normal file
View File

@ -0,0 +1,20 @@
#include <stdio.h>
#include <string.h>
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;
}

44
day12/d18.c Normal file
View File

@ -0,0 +1,44 @@
#include <stdio.h>
#include <string.h>
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);
}

37
day12/d19.c Normal file
View File

@ -0,0 +1,37 @@
#include <stdio.h>
#include <string.h>
#include <math.h> // 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;
}

23
day12/d20.c Normal file
View File

@ -0,0 +1,23 @@
#include <stdio.h>
#include <string.h>
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;
}

24
day12/d20_2.c Normal file
View File

@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 结构体存在堆区,结构体的成员也存在堆区
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;
}

31
day12/d21.c Normal file
View File

@ -0,0 +1,31 @@
// 浅拷贝
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;
}

59
day12/d9.c Normal file
View File

@ -0,0 +1,59 @@
// 结构体,也是构造类型之一,由至少一个基本数据类型或构造类型组成的一种数据类型
// 结构体的成员可以是基本数据类型或构造类型
#include <stdio.h>
#include <string.h>
/*
// 语法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;
}