能不能解释一下这个程序每行代码的意思

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>typedef struct _employee{ char name[20]; //员工姓名 char phone[12]; //员工电话 char addr[20]; //住址 char cardId[20]; //身份证号 char department[20]; //部门 char id[10]; //工号 int workDay; //工作天数 char jiguan[20]; //籍贯 float workAge; //工龄 char isMarrid; //婚姻 int age; //年龄 char sex; //性别 int child; //是否生育,0表示未生育,>0表示孩子个数 char grade[20]; //学历 int isIn; //公司文化活动是否签到 float base; //基础工资 float money; //薪资 float sale; //销售金额 float total; //总计}Employee;const char* g_title[] = { "员工姓名","员工电话","住址","身份证号","部门","工号","工作天数","籍贯","工龄","婚姻状况","年龄","性别","生育状况","学历","公司文化活动签到" };//显示单个员工信息void showSingle(Employee emp){ printf("员工姓名:%s\n", emp.name); printf("员工电话:%s\n", emp.phone); printf("住址:%s\n", emp.addr); printf("身份证号:%s\n", emp.cardId); printf("部门:%s\n", emp.department); printf("工号:%s\n", emp.id); printf("工作天数:%d\n", emp.workDay); printf("工龄:%.1f\n", emp.workAge); printf("婚姻状况:"); if (emp.isMarrid == 'y' || emp.isMarrid == 'Y') printf("已婚\n"); else printf("未婚\n"); printf("年龄:%d\n", emp.age); printf("性别:"); if (emp.sex == 'F' || emp.sex == 'f') printf("女\n"); else printf("男\n"); printf("剩余状况:"); if (emp.child <= 0) printf("无\n"); else printf("%d个子女\n", emp.child); printf("学历:%s\n", emp.grade); printf("公司文化活动签到:"); if (emp.isIn == 1) printf("是\n"); else if (emp.isIn == 0) printf("否,但已请假\n"); else printf("否,未请假\n");}//显示所有员工信息void showAll(char* name, Employee emp[], int n){ int i = 0, j = 0; printf("单位名称:%s \t 总人数:%d\n", name, n); printf("------------------------------------------\n"); system("cls"); for (i = 0; i < n; i++) { showSingle(emp[i]); printf("------------------------------------------\n"); } }//查找void search(Employee emp[], int n){ int op; int i = 0; char buf[20] = { 0 }; system("cls"); printf("1.根据工号查询\n"); printf("2.根据姓名查询\n"); printf("3.根据电话查询\n"); printf("4.返回上一层\n"); while (1) { scanf("%d", &op); if (op >= 1 && op <= 4) system("cls"); break; } switch (op) { case 1: printf("请输入工号:"); scanf("%s", buf);system("cls"); break; case 2: printf("请输入姓名:"); scanf("%s", buf);system("cls"); break; case 3: printf("请输入电话:"); scanf("%s", buf);system("cls"); break; case 4: return; } for (i = 0; i < n; i++) { if (op == 1 && strcmp(emp[i].id, buf) == 0) { showSingle(emp[i]); break; } else if (op == 2 && strcmp(emp[i].name, buf) == 0) { showSingle(emp[i]); break; } else if (op == 3 && strcmp(emp[i].phone, buf) == 0) { showSingle(emp[i]); break; } } if (i == n) printf("未找到符合条件的员工!!\n");}//筛选void select(Employee emp[], int n){ int i, op; char buf[20] = { 0 }, tmp; int flag = 0; int age; system("cls"); printf("1.通过部门筛选\n"); printf("2.通过性别筛选\n"); printf("3.通过年龄筛选\n"); printf("4.通过婚姻状况筛选\n"); printf("5.通过请假考勤\n"); printf("6.通过学历筛选\n"); printf("7.通过籍贯筛选\n"); printf("8.返回上一层\n"); while (1) { scanf("%d", &op); if (op >= 1 && op <= 8) system("cls"); break; } switch (op) { case 1: printf("请输入部门:"); scanf("%s", buf); for (i = 0; i < n; i++) { if (strcmp(buf, emp[i].department) == 0) { printf("------------------------------------------\n"); flag = 1; showSingle(emp[i]); } } if (flag == 0) printf("未找到符合条件的员工!!\n"); break; case 2: printf("请输入性别:"); fflush(stdin); buf[0] = getchar(); buf[0] = toupper(buf[0]); for (i = 0; i < n; i++) { tmp = toupper(emp[i].sex); if (buf[0] == tmp) { printf("------------------------------------------\n"); showSingle(emp[i]); flag = 1; } } if (flag == 0) printf("未找到符合条件的员工!!\n"); break; case 3: printf("请输入年龄:"); scanf("%d", &age); for (i = 0; i < n; i++) { if (emp[i].age == age) { printf("------------------------------------------\n"); showSingle(emp[i]); flag = 1; } } if (flag == 0) printf("未找到符合条件的员工!!\n"); break; case 4: printf("请输入婚姻状况(Y:已婚 N:未婚 ): "); rewind(stdin); buf[0] = getchar(); buf[0] = toupper(buf[0]); for (i = 0; i < n; i++) { tmp = toupper(emp[i].isMarrid); if (buf[0] == tmp) { printf("------------------------------------------\n"); showSingle(emp[i]); flag = 1; } } if (flag == 0) printf("未找到符合条件的员工!!\n"); break; case 5: printf("请输入筛选条件(1.请假 2.未请假\n): "); scanf("%d", &age); for (i = 0; i < n; i++) { if (emp[i].workDay < 22) { printf("------------------------------------------\n"); showSingle(emp[i]); flag = 1; } } if (flag == 0) printf("未找到符合条件的员工!!\n"); break; case 6: printf("请输入学历:"); scanf("%s", buf); for (i = 0; i < n; i++) { if (strcmp(buf, emp[i].grade) == 0) { printf("------------------------------------------\n"); showSingle(emp[i]); flag = 1; } } if (flag == 0) printf("未找到符合条件的员工!!\n"); break; case 7: printf("请输入籍贯:"); scanf("%s", buf); for (i = 0; i < n; i++) { if (strcmp(buf, emp[i].jiguan) == 0) { printf("------------------------------------------\n"); showSingle(emp[i]); flag = 1; } } if (flag == 0) printf("未找到符合条件的员工!!\n"); break; case 8: return; }}//插入新员工int insert(Employee emp[], int n){ system("cls"); printf("更新该员工信息:\n"); printf("请输入员工姓名:"); scanf("%s", emp[n].name); printf("请输入员工电话:"); scanf("%s", emp[n].phone); printf("请输入住址:"); scanf("%s", emp[n].addr); printf("请输入身份证号:"); scanf("%s", emp[n].cardId); printf("请输入部门:"); scanf("%s", emp[n].department); printf("请输入工号:"); scanf("%s", emp[n].id); printf("请输入工作天数:"); scanf("%d", &emp[n].workDay); printf("请输入籍贯:"); scanf("%s", emp[n].jiguan); printf("请输入工龄:"); scanf("%f", &emp[n].workAge); printf("请输入婚姻状况(Y:已婚 N:未婚):"); rewind(stdin); emp[n].isMarrid = getchar(); printf("请输入年龄:"); scanf("%d", &emp[n].age); printf("请输入性别(F:女 M:男):"); rewind(stdin); emp[n].sex = getchar(); printf("请输入生育情况:"); scanf("%d", &emp[n].child); printf("请输入学历:"); scanf("%s", emp[n].grade); printf("公司文化活动签到(1.签到 0.未参加但请假 -1.未参加未请假):"); scanf("%d", &emp[n].isIn); printf("请输入员工基础薪资:"); scanf("%f", &emp[n].base); printf("请输入销售金额:"); scanf("%f", &emp[n].sale); printf("新员工信息已插入!\n"); return (n + 1);}//删除旧员工信息int dele(Employee emp[], int n){ char buf[20] = { 0 }; int i, flag = 0, j; system("cls"); printf("请输入要删除的员工工号:"); scanf("%s", buf); for (i = 0; i < n; i++) { if (strcmp(buf, emp[i].id) == 0) { flag = 1; for (j = i; j < n - 1; j++) emp[j] = emp[j + 1]; printf("该员工信息已删除!!\n"); return (n - 1); } } if (flag == 0) printf("未找到符合条件的员工!!\n"); return n;}//薪资void caculate(Employee emp[], int n){ int i = 0; system("cls"); for (i = 0; i < n; i++) { emp[i].total = emp[i].base / 22 * emp[i].workDay; if (strcmp(emp[i].grade, "专科") == 0) emp[i].total += 800; else if (strcmp(emp[i].grade, "本科") == 0) emp[i].total += 1000; else if (strcmp(emp[i].grade, "研究生") == 0) emp[i].total += 1200; //生育奖 if (emp[i].child == 1) emp[i].total += 500; else if (emp[i].child == 2) emp[i].total += 750; else if (emp[i].child == 3) emp[i].total += 1000; //工龄奖 emp[i].total += emp[i].workAge * 50; //提成 if (emp[i].sale < 1000000) emp[i].total += emp[i].sale * 0.02; else if (emp[i].sale < 1000000) emp[i].total += emp[i].sale * 0.05; else emp[i].total += emp[i].sale * 0.08; //公司互动 if (emp[i].isIn == 1) emp[i].total += 150; else if (emp[i].isIn == 0) emp[i].total += 100; printf("工号:%s 姓名:%s 薪资:%.2f\n", emp[i].id, emp[i].name, emp[i].total); }}//计算每月应缴金额void jiaona(Employee emp[], int n){ int i; float f1, f2; for (i = 0; i < n; i++) { system("cls"); printf("工号:%s 姓名:%s 薪资:%.2f ", emp[i].id, emp[i].name, emp[i].total); f1 = emp[i].total * 0.02 + 7; f2 = emp[i].total * 0.05; printf("医保缴纳:%.2f 公积金缴纳:%.2f 实发工资:%.2f\n", f1, f2, (emp[i].total - f1 - f2)); }}//显示销售前3名void showBef(Employee emp[], int n){ int i, j; Employee t; //根据销售额排名 system("cls"); for (i = 0; i < n - 1; i++) { for (j = 0; j < n - 1 - i; j++) { if (emp[j].sale < emp[j + 1].sale) { t = emp[j]; emp[j] = emp[j + 1]; emp[j + 1] = t; } } } //显示前三名 for (i = 0; i < 3; i++) { printf("工号:%s 姓名:%s 销售额:%.2f\n", emp[i].id, emp[i].name, emp[i].sale); }}//写文件void write2File(const char* filename, Employee emp[], int n){ FILE* fp = fopen(filename, "wb"); int i = 0; for (; i < n; i++) { fwrite(&emp[i], 1, sizeof(Employee), fp); } fclose(fp);}//读文件int readFile(const char* filename, Employee emp[], int n){ FILE* fp = fopen(filename, "rb"); if (fp == 0) { printf("文件打开失败\n"); return n; } while (!feof(fp)) { if (fread(&emp[n], 1, sizeof(Employee), fp)) n++; } fclose(fp); return n;}int main(){ int op; Employee emp[100]; int n = 0; char name[20]; const char* filename = "record.txt"; //读文件1 n = readFile(filename, emp, n); while (1) { system("cls"); strcpy(name,"麻豆传媒有限公司"); printf("欢迎来到麻豆传媒有限公司\n"); printf("1.插入新员工信息\n"); printf("2.删除旧员工信息\n"); printf("3.查找\n"); printf("4.筛选\n"); printf("5.显示全部信息\n"); printf("6.计算薪资\n"); printf("7.计算每月应缴纳金额并显示实发金额\n"); printf("8.显示销冠前三名\n"); printf("9.写入文件\n"); printf("0.退出系统\n"); scanf("%d", &op); switch (op) { case 1: n = insert(emp, n); break; case 2: n = dele(emp, n); break; case 3: search(emp, n); break; case 4: select(emp, n); break; case 5: showAll(name, emp, n); break; case 6: caculate(emp, n); break; case 7: jiaona(emp, n); break; case 8: showBef(emp, n); break; case 9: write2File(filename, emp, n); break; case 0: return 0; default: break; } system("pause"); }}

全部贴上来字数超限了,这里贴一部分,评论里贴一部分。如下:

#define  _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct _employee
{
    char name[20];   //员工姓名
    char phone[12];  //员工电话
    char addr[20];   //住址
    char cardId[20]; //身份证号
    char department[20]; //部门
    char id[10];     //工号
    int workDay;     //工作天数
    char jiguan[20]; //籍贯
    float workAge;     //工龄
    char isMarrid;    //是否已婚
    int age; //年龄
    char sex;  //性别
    int child;  //是否生育,0表示未生育,>0表示孩子个数
    char grade[20]; //学历
    int isIn; //公司文化活动是否签到
    float base; //基础工资
    float money; //薪资
    float sale; //销售金额
    float total; //总计
}Employee;

//显示内容,这个地方没用,可以删掉
//const char* g_title[] = { "员工姓名","员工电话","住址","身份证号","部门","工号","工作天数","籍贯","工龄","婚姻状况","年龄","性别","生育状况","学历","公司文化活动签到" };

/**功能:显示单个员工信息,为了便于显示,显示单个员工信息单独封装了一个函数,方便修改显示格式
* void 是函数返回值类型,void表示函数没有返回值
* showSingle 是函数名,()里面是参数列表,Employee emp表示函数参数是一个Employee类型的结构体,emp是形参
*/
void showSingle(Employee emp)
{
    printf("员工姓名:%s\n", emp.name);
    printf("员工电话:%s\n", emp.phone);
    printf("住址:%s\n", emp.addr);
    printf("身份证号:%s\n", emp.cardId);
    printf("部门:%s\n", emp.department);
    printf("工号:%s\n", emp.id);
    printf("工作天数:%d\n", emp.workDay);
    printf("工龄:%.1f\n", emp.workAge);
    printf("婚姻状况:");
    if (emp.isMarrid == 'y' || emp.isMarrid == 'Y')  //如果是y或者Y,表示已婚
        printf("已婚\n");
    else
        printf("未婚\n");
    printf("年龄:%d\n", emp.age);
    printf("性别:");
    if (emp.sex == 'F' || emp.sex == 'f')
        printf("女\n");
    else
        printf("男\n");
    printf("生育状况:");
    if (emp.child <= 0)  //0或者负数表示没有生育,正整数表示有几个孩子
        printf("无\n");
    else
        printf("%d个子女\n", emp.child);
    printf("学历:%s\n", emp.grade);
    printf("公司文化活动签到:");
    if (emp.isIn == 1)
        printf("是\n");
    else if (emp.isIn == 0)
        printf("否,但已请假\n");
    else
        printf("否,未请假\n");

    //下面的信息题目没有要求显示,可以根据需要删除
    printf("基础工资:%.2f\n", emp.base);
    printf("销售金额:%.2f\n", emp.sale);

}
/**功能:显示所有员工信息
* void 是函数返回值类型,void表示函数没有返回值
* showAll 是函数名,()里面是参数列表,
* char* name,是传进来的单位名称,是一个字符指针,改成char name[20]也行
* Employee emp[],说明emp是一个Employee结构体数组,int n用来说明结构体数组中实际元素的个数
*/
void showAll(char* name, Employee emp[], int n)
{
    int i = 0, j = 0;
    printf("单位名称:%s \t  总人数:%d\n", name, n);
    printf("------------------------------------------\n");
    for (i = 0; i < n; i++) //遍历所有员工信息
    {
        showSingle(emp[i]); //调用showSingle,显示每个员工信息
    }
    printf("------------------------------------------\n");
}

/**功能:查询,支持工号查询、姓名查询和电话查询
* void 是函数返回值类型,void表示函数没有返回值
* search 是函数名,()里面是参数列表,
* Employee emp[],说明emp是一个Employee结构体数组,int n用来说明结构体数组中实际元素的个数
*/
void search(Employee emp[], int n)
{
    int op;
    int i = 0;
    char buf[20] = { 0 };
    printf("1.根据工号查询\n");
    printf("2.根据姓名查询\n");
    printf("3.根据电话查询\n");
    printf("4.返回上一层\n");
    while (1)
    {
        scanf("%d", &op);  //输入选择
        if (op >= 1 && op <= 4)  //如果输入的数字不再1-4之间,就重新输入
            break;
    }
    switch (op)
    {
    case 1: printf("请输入工号:"); scanf("%s", buf); break; //输入工号
    case 2: printf("请输入姓名:"); scanf("%s", buf); break; //输入姓名
    case 3: printf("请输入电话:"); scanf("%s", buf); break; //输入电话
    case 4: return;  //输入4表示结束本子菜单,返回到main函数主程序,也就是主菜单
    }
    for (i = 0; i < n; i++)  //遍历所有员工进行查询
    {
        if (op == 1 && strcmp(emp[i].id, buf) == 0)  //根据工号查询,strcmp用来比较两个字符串是否一致
        {
            showSingle(emp[i]);  //找到符合条件的员工后显示其信息
            break;
        }
        else if (op == 2 && strcmp(emp[i].name, buf) == 0) //根据姓名查询
        {
            showSingle(emp[i]);
            break;
        }
        else if (op == 3 && strcmp(emp[i].phone, buf) == 0) //根据电话查询
        {
            showSingle(emp[i]);
            break;
        }
    }
    if (i == n)
        printf("未找到符合条件的员工!!\n");
}


/**功能:筛选,支持部门筛选、性别筛选、年龄筛选、婚姻状况筛选、请假考勤、学历筛选籍贯筛选
* void 是函数返回值类型,void表示函数没有返回值
* search 是函数名,()里面是参数列表,
* Employee emp[],说明emp是一个Employee结构体数组,int n用来说明结构体数组中实际元素的个数
*/
void select(Employee emp[], int n)
{
    int i, op;
    char buf[20] = { 0 }, tmp;
    int flag = 0;
    int age;
    printf("1.通过部门筛选\n");
    printf("2.通过性别筛选\n");
    printf("3.通过年龄筛选\n");
    printf("4.通过婚姻状况筛选\n");
    printf("5.通过请假考勤\n");
    printf("6.通过学历筛选\n");
    printf("7.通过籍贯筛选\n");
    printf("8.返回上一层\n");
    while (1)
    {
        scanf("%d", &op); //输入功能选择
        if (op >= 1 && op <= 8) //判断输入是否在1-8之间,不是则重新输入
            break;
    }
    switch (op)
    {
    case 1:
        printf("请输入部门:");
        scanf("%s", buf);  
        for (i = 0; i < n; i++)  //遍历员工数组
        {
            if (strcmp(buf, emp[i].department) == 0) //判断数组中的员工的部门是否与许需要查询的一致
            {
                flag = 1;
                showSingle(emp[i]);
            }
        }
        if (flag == 0)
            printf("未找到符合条件的员工!!\n");
        break;
    case 2:
        printf("请输入性别:");
        rewind(stdin); //或者 fflush(stdin); 清空输入缓存,避免缓存中有回车符对后面的输入有影像
        buf[0] = getchar();
        buf[0] = toupper(buf[0]);  //把小写字符转成大写字符,方便对比
        for (i = 0; i < n; i++)
        {
            tmp = toupper(emp[i].sex);
            if (buf[0] == tmp)  //判断数组中的员工的性别是否与许需要查询的一致
            {
                showSingle(emp[i]);
                flag = 1;
            }
        }
        if (flag == 0)
            printf("未找到符合条件的员工!!\n");
        break;
    case 3:
        printf("请输入年龄:");
        scanf("%d", &age);
        for (i = 0; i < n; i++)
        {
            if (emp[i].age == age) //判断数组中的员工的年龄是否与许需要查询的一致
            {
                showSingle(emp[i]);
                flag = 1;
            }
        }
        if (flag == 0)
            printf("未找到符合条件的员工!!\n");
        break;
    case 4:
        printf("请输入婚姻状况(Y:已婚   N:未婚 ):  ");
        rewind(stdin);
        buf[0] = getchar();
        buf[0] = toupper(buf[0]);
        for (i = 0; i < n; i++)
        {
            tmp = toupper(emp[i].isMarrid); //判断数组中的员工的婚姻状况是否与许需要查询的一致
            if (buf[0] == tmp)
            {
                showSingle(emp[i]);
                flag = 1;
            }
        }
        if (flag == 0)
            printf("未找到符合条件的员工!!\n");
        break;
    case 5:
        printf("请输入筛选条件(1.请假  2.未请假\n): ");
        scanf("%d", &age);
        for (i = 0; i < n; i++)
        {
            if (emp[i].workDay < 22) //这里通过工作天数来判断是否请假,小于22天说明有请假,22天是根据题目中薪资计算工时来的
            {
                showSingle(emp[i]);
                flag = 1;
            }
        }
        if (flag == 0)
            printf("未找到符合条件的员工!!\n");
        break;
    case 6:
        printf("请输入学历:");
        scanf("%s", buf);
        for (i = 0; i < n; i++)
        {
            if (strcmp(buf, emp[i].grade) == 0) //判断数组中的员工的学历是否与许需要查询的一致
            {
                showSingle(emp[i]);
                flag = 1;
            }
        }
        if (flag == 0)
            printf("未找到符合条件的员工!!\n");
        break;
    case 7:
        printf("请输入籍贯:");
        scanf("%s", buf);
        for (i = 0; i < n; i++)
        {
            if (strcmp(buf, emp[i].jiguan) == 0) //判断数组中的员工的籍贯是否与许需要查询的一致
            {
                showSingle(emp[i]);
                flag = 1;
            }
        }
        if (flag == 0)
            printf("未找到符合条件的员工!!\n");
        break;
    case 8:
        return;
    }
}
/**功能:插入新员工
* int 说明函数的返回值是一个整数,这里用来返回插入新员工后,总的员工个数
* insert 是函数名,()里面是参数列表,
* Employee emp[],说明emp是一个Employee结构体数组,int n用来说明结构体数组中实际元素的个数
*/
int insert(Employee emp[], int n)
{
    printf("更新该员工信息:\n");
    printf("请输入员工姓名:"); scanf("%s", emp[n].name);  //根据提示输入员工信息
    printf("请输入员工电话:"); scanf("%s", emp[n].phone);
    printf("请输入住址:"); scanf("%s", emp[n].addr);
    printf("请输入身份证号:"); scanf("%s", emp[n].cardId);
    printf("请输入部门:"); scanf("%s", emp[n].department);
    printf("请输入工号:"); scanf("%s", emp[n].id); //也可以不改工号
    printf("请输入工作天数:"); scanf("%d", &emp[n].workDay);
    printf("请输入籍贯:"); scanf("%s", emp[n].jiguan);
    printf("请输入工龄:"); scanf("%f", &emp[n].workAge);
    printf("请输入婚姻状况(Y:已婚  N:未婚):"); rewind(stdin); emp[n].isMarrid = getchar();
    printf("请输入年龄:"); scanf("%d", &emp[n].age);
    printf("请输入性别(F:女  M:男):"); rewind(stdin); emp[n].sex = getchar();
    printf("请输入生育情况:"); scanf("%d", &emp[n].child);
    printf("请输入学历:"); scanf("%s", emp[n].grade);
    printf("公司文化活动签到(1.签到  0.未参加但请假  -1.未参加未请假):"); scanf("%d", &emp[n].isIn);
    printf("请输入员工基础薪资:"); scanf("%f", &emp[n].base);
    printf("请输入销售金额:"); scanf("%f", &emp[n].sale);
    printf("新员工信息已插入!\n");
    return (n + 1);  //员工数量+1
}


/**功能:删除旧员工信息
* int 说明函数的返回值是一个整数,这里用来返回删除员工后,剩余的员工个数(如果查询不到员工,会导致删除失败)
* dele 是函数名,()里面是参数列表,
* Employee emp[],说明emp是一个Employee结构体数组,int n用来说明结构体数组中实际元素的个数
*/
int dele(Employee emp[], int n)
{
    char buf[20] = { 0 };
    int i, flag = 0, j;
    printf("请输入要删除的员工工号:");
    scanf("%s", buf);
    for (i = 0; i < n; i++)  //遍历所有员工
    {
        if (strcmp(buf, emp[i].id) == 0)  //对比员工的工号与要删除的工号是否一致
        {
            flag = 1;
            for (j = i; j < n - 1; j++)  //找到要删除的员工后,把该员工后面的员工信息在数组中往前移动一个1位置,也就是把,要删除的员工数据从数组中删除
                emp[j] = emp[j + 1];
            printf("该员工信息已删除!!\n");
            return (n - 1);
        }
    }
    if (flag == 0)
        printf("未找到符合条件的员工!!\n");
    return n;
}

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632