day18 结构体

有参宏和函数的区别

1.展开时机:有参宏而言,在预处理阶段展开,而函数在调用时才展开

2.内存使用:有参宏而言,占用的是所在函数的空间,而函数在调用时会单独开辟空间

3.效率上:有参宏的效率比函数有的效率高

4.有参宏是宏定义,只替换不计算不做正确性检查,而函数调用要符合函数的调用标准,形参会进行计算

结构体

概念:结构体是由相同数据类型或不同数据类型构成的连续存储的变量的集合,结构体属于构造数据类型

定义格式

struct  结构体名

{

成员类型1 成员变量1;

成员类型2 成员变量2;

......

}

注意事项:

1.struct是结构体的关键字,在C语言中定义结构体时不能省略

2.struct后面跟的是结构体类型名,类似于int  float  double

3.所有的结构体成员属性使用一对花括号包裹,每个成员之间使用分号隔开

4.成员变量的类型,可以是任意类型(可以是基本数据类型,也可以是构造数据类型、指针类型、空类型)

5.花括号后的分号绝对不能省略

struct  Student     //若没有student(结构体名)后续便不能继续定义结构体变量
{int num;        //学号char name[20];       //姓名double score;       //成绩char sex;           //性别char TEL[11];        //手机号
}s1,s2;
//定义结构体类型时顺便定义了两个结构体变量/*struct student s1,s2;*/

结构体可以定义在程序的任何地方,可以定义在函数体内也可以定义在函数体外,但是必须要定义在使用之前    一般定义在函数体外,分文件编译时,通常定义在头文件内

结构体变量的初始化,也有三种方式,初始化时所有成员是花括号包裹,每个成员之间使用逗号隔开

//定义一个结构体类型
struct  Student
{int num;        //学号char name[20];       //姓名double score;       //成绩char sex;           //性别char TEL[11];        //手机号
};//在程序中
struct  Student  s1 = {1001, "张三", 99.5, 'M', "13888888888"};    //定义了一个结构体变量并初始化
//定义一个结构体类型
struct  Student
{int num;        //学号char name[20];       //姓名double score;       //成绩char sex;           //性别char TEL[11];        //手机号
}s1 = {1002, "李四", 99.8, 'W',13888888888};

定义结构体变量并给部分成员初始化

struct  Student
{int num;        //学号char name[20];       //姓名double score;       //成绩char sex;           //性别char TEL[11];        //手机号
};//在程序中
struct  Student  s1 = {.num="张三", .score=99.5};    //定义了一个结构体变量并初始化

2.4结构体类型访问成员

1.结构体变量访问成员,使用成员.运算符来完成

        使用方法:变量名.成员名;

2.结构体指针访问成员,使用成员运算符->来完成

        使用方法:指针变量->成员名;

3.虽然这两个运算符是双目运算符但是拥有较高的优先级。比单目运算符优先级高

4.上面两个运算执行后结果是 成员类型,跟结构体变量和结构体指针就没有关系了

5.不要试图通过结构体变量名,操作所有成员,只能通过成员运算符一个一个操作

6.结构体变量支持两种运算:取地址运算、赋值运算

7.结构体类型中,也可以有另一个结构体变量,访问最里层的成员时需要成员运算符一级一级找到最低一级 

#include<myhead.h>struct Student;      //结构体类型的声明//定义一个生日类型
struct Birthday
{int year;     //年份int month;      //月份int day;       //日
};//定义结构体类型
struct Student
{int num;    //学号char name[20];      //姓名double score;      //成绩struct Birthday bir;      //生日} s1 = {1002, "张三", 99.5};        //分号不能省略int main(int argc, const char *argv[])
{//使用结构体类型定义变量并初始化struct Student s2 = {1001, "zhangpp", 99, {2000,2,20}};struct Student s3 = {.num=1003, .score=100};   //对部分成员初始化s1.num = 9527;       //使用成员运算符对成员进行操作printf("s1.num = %d, s1.name=%s, s1.score=%.2lf\n", \s1.num, s1.name, s1.score);//printf("%s\n", s1);        //不可以通过结构体变量名输出所有成员printf("&s1 = %p\n", &s1);    //输出的是s1的地址struct Student *ptr = &s1;    //结构体指针变量ptr->num = 9999;printf("ptr->num = %d, ptr->name=%s, ptr->score=%.2lf\n", \ptr->num, ptr->name, ptr->score);//结构体变量支持赋值运算s1 = s2;printf("ptr->num = %d, ptr->name=%s, ptr->score=%.2lf\n", \ptr->num, ptr->name, ptr->score);//访问结构体成员中的结构体变量s1.bir.year = 2024;     //需要使用成员运算符一级一级找到最低一级ptr->bir.month = 3;    printf("生日:%d-%d-%d\n", ptr->bir.year, ptr->bir.month, ptr->bir.day);return 0;
}

结构体数组

1.本质是一个数值,每个元素都是结构体变量

2.结构体数组的定义和使用跟普通数组一致,但是,访问到数组元素时,每个元素需要继续是成员运算符找到其结构体成员进行操作

#include<myhead.h>//定义一个英雄类型
struct Hero
{char name[20];       //英雄名称int kill;           //击杀人头数int die;            //死亡此处int assist;         //辅助次数
};//定义函数,录入英雄本局比赛的信息
void input_hero_msg(struct Hero *ptr, int n)
{//录入信息for(int i=0; i<n; i++){printf("请输入第%d个英雄的名称:", i+1);scanf("%s", ptr[i].name);     //(ptr+i)->nameprintf("请输入第%d个英雄的人头数:", i+1);scanf("%d", &ptr[i].kill);printf("请输入第%d个英雄的死亡数:", i+1);scanf("%d", &ptr[i].die);printf("请输入第%d个英雄的辅助数:", i+1);scanf("%d", &ptr[i].assist);printf("\n");}printf("录入成功\n");
}//定义输出函数
void output_hero_msg(struct Hero *ptr, int n)
{printf("本局比赛结算如下:\n");printf("英雄\tkill\tdie\tassist\n");for(int i=0; i<n; i++){printf("%s\t%d\t%d\t%d\n", ptr[i].name,ptr[i].kill, ptr[i].die, ptr[i].assist);}
}//定义求mvp函数
struct Hero mvp_hero(struct Hero *ptr, int n)
{struct Hero mvp = ptr[0];   //将第一个英雄当做mvpfor(int i=0; i<n; i++){//拿着当前mvp的数据跟任意一个进行比较if( mvp.kill*0.9+mvp.assist*0.5-mvp.die*0.4  < \ptr[i].kill*0.9+ptr[i].assist*0.5-ptr[i].die*0.4 ){//更新mvpmvp = ptr[i];}}//将mvp返回return mvp;}int main(int argc, const char *argv[])
{//定义数组存储五个英雄struct Hero hero[5];    //hero[0]---hero[4]//录入英雄的信息input_hero_msg(hero, 5);//输出英雄信息output_hero_msg(hero, 5);//求 mvp struct Hero res = mvp_hero(hero, 5);printf("本局比赛的mvp为:%s,%d,%d,%d\n", \res.name,res.kill,res.die,res.assist);return 0;
}

结构体大小

1.定义结构体类型时,系统不分配内存空间,只有使用结构体类型定义变量时才分配内存空间

2.系统为结构体变量分配的空间是连续的,系统会将结构体每个成员看成一个整体进行操作

3.结构体大小:是每个成员变量所占内存大小之和-->字节对齐原则

        结构体变量实际大小>=各个成员变量所占内存之和

4.C语言中,一个空的结构体所占内存为0字节

#include<myhead.h>struct AA            //空结构体所占内存为0字节
{
};struct BB            //只有一个字符成员
{char value;      // 1 
};struct CC               //有两个成员
{short key;          // 1120char value;
};struct DD           //有三个成员
{short key;char value;int temp;           //11203333
};struct EE          //两个成员
{char value;int temp;      //10002222
};struct FF            //有四个成员
{int num;char value;char *ptr;short key;   // 111120003333333344000000
};struct GG            //有四个成员
{char *ptr;int num;char value;short key;   // 1111111122223044
};struct HH                  //一个普通变量和一个结构体变量
{short num;struct EE value;    //110010002222
};struct II           //一个普通变量和一个结构体变量
{char temp;struct GG g;     // 100000001111111122223044};int main(int argc, const char *argv[])
{printf("sizeof(struct AA) = %zd\n", sizeof(struct AA));    //0printf("sizeof(struct BB) = %zd\n", sizeof(struct BB));    //1printf("sizeof(struct CC) = %zd\n", sizeof(struct CC));    //4struct CC c;printf("&c=%p, &c.value=%p, &c.key = %p\n", \&c, &c.value, &c.key);printf("sizeof(struct DD) = %zd\n", sizeof(struct DD));    //8printf("sizeof(struct EE) = %zd\n", sizeof(struct EE));    //8printf("sizeof(struct FF) = %zd\n", sizeof(struct FF));    //24printf("sizeof(struct GG) = %zd\n", sizeof(struct GG));    //16printf("sizeof(struct HH) = %zd\n", sizeof(struct HH));    //12struct HH h;printf("&h=%p, &h.num=%p, &h.value = %p, &h.value.value=%p, &h.value.temp=%p\n", \&h, &h.num, &h.value, &h.value.value, &h.value.temp);printf("sizeof(struct II) = %zd\n", sizeof(struct II));    //24return 0;
}

特殊关键字的使用

const

1.在定义变量后,变量有两个属性,读属性(获取值)写属性(修改值)

2.const:保护数据的作用,给变量以常属性

3.const的用法

        const可以修饰普通变量:修饰普通变量时表示给该变量以常属性(不能通过该变量进行写操作)

        const修饰的局部变量,必须进行初始化,如果不初始化,则为随机值,并且后期不能更改,可以使用指针指向该变量,使用指针更改其值是没有问题的

#include<myhead.h>int main(int argc, const char *argv[])
{//1、const修饰普通变量const int num = 520;printf("num = %d\n", num);   //具有读属性//num = 1314;       //不能通过变量名进行更改int *ptr = &num;    //定义指针指向num*ptr = 1314;       //使用指针更改num的值printf("num = %d\n", num);   //具有读属性return 0;
}

const修饰指针变量

const int*ptr:保护的是指针指向内存空间的值,指针的指向可以改变,但是不能通过改变指针改变其指向内存空间的值

int const *ptr:保护的是指针指向内存空间的值,指针的指向可以改变,但是不能通过改变指针改变其指向内存空间的值

int *const ptr:保护的是指针的值(指针指向)。指针指向不可以改变,但是可以通过指针改变其指向的内存空间中的值

const int *const ptr:全部进行保护,既不能改变指针的指向,也不能通过指针改变其指向内存空间中的值

#include<myhead.h>int main(int argc, const char *argv[])
{int num = 520;      //普通变量int key = 1314;//定义指针变量const int *ptr1 = &num;   //保护指针指向的内存空间中的值//*ptr1 = 666;          //执行不成功 不能进行写操作printf("*ptr1 = %d\n", *ptr1);ptr1 = &key;             //可以改变指针的指向//定义指针变量int const *ptr2 = &num;   //保护指针指向的内存空间中的值//*ptr2 = 666;          //执行不成功 不能进行写操作printf("*ptr2 = %d\n", *ptr2);ptr2 = &key;             //可以改变指针的指向//定义指针变量int * const ptr3 = &num;  //保护的是指针的指向(指针的值)*ptr3 = 666;          //可以通过指针改变指向的内存空间中的值printf("*ptr3 = %d\n", *ptr3);   //读取数据//ptr3 = &key;               //不可以改变指针的值(指向)//定义指针变量const int *const ptr4 = &num;//*ptr4 = 999;          //不可以通过指针改变指向的内存空间中的值//ptr4 = &key;          //不可以改变指针的指向return 0;
}

const修饰函数的形式参数,表示保护形参数据不被修改

#include<myhead.h>//保护形参的指向不被修改
void fun(int * const ptr)
{//如果没有保护指针的指向,那么下面会出现段错误if(ptr=NULL){}*ptr = 1314;
}//保护传入的指针指向的内存空间中的值不会在函数体内被更改
void hun(const char *ptr)
{//如果没有保护指针指向的空间的值,则下面程序会出现段错误ptr[0] = 'A';
}int main(int argc, const char *argv[])
{int num = 520;fun(&num);        //调用函数传递地址printf("num = %d\n", num);hun("hello a");   //调用函数传递一个字符串return 0;
}

const修饰函数的返回值,表示保护函数的返回结果不被修改,常用于指针函数

*fun() = 520
ubuntu@ubuntu:day17$ cat 08const.c 
#include<myhead.h>//const修饰的函数,称为常函数,表示保护返回结果不能被修改
const int *fun()
{static int num = 520;return &num;         //指针函数返回静态局部变量的地址
}int main(int argc, const char *argv[])
{//*fun() = 1314;       //不能被修改,因为函数由const修饰了printf("*fun() = %d\n", *fun());     //?return 0;
}

static

1> static修饰局部变量,表示相当于在函数体内定义一个全局变量,该变量的生命周期不会随着所在函数的开始而开始结束而结束,并且static修饰的变量的空间不依附所在函数。其生命周期从程序运行时就开始了。

2> static修饰全局变量,表示该变量只能在所在文件中使用,不能被其他文件所引入

3> static修饰函数时,表示该函数也只能在该文件中被使用,其他文件不能使用

extern

1.可以在某个文件中使用extern来引入其他文件中的全局变量

2.在局部变量和全局变量同名时,函数体内优先使用局部变量,如果非要使用全局变量,可以使用extern引入后使用

#include<myhead.h>int num = 520;      //全局变量int main(int argc, const char *argv[])
{int num = 1314;           //局部变量if(1){extern int num;     //引入外部变量printf("num = %d\n", num);         //?}return 0;
}

作业

1> 使用结构体数组完成班级学生管理系统,学生类型中包含 (学号、姓名、成绩、性别、TEL)

2> 完成菜单选项

3> 功能1:信息录入,提示并输入班级人数,完成每个学生信息的录入

4> 功能2:信息展示

5> 功能3:添加一个学生操作

6> 功能4:提示并输入一个学号,并将该学号对应的学生信息删除

7> 功能5:提示并输入一个学生姓名,更改其联系方式

8> 功能6:提示并输入一个学生姓名,展示该学生的所有信息

9> 功能7:将学生按成绩进行降序排序

10> 功能0:退出系统

#include<luochen.h>
#include "homework.h"int menu()
{int menu;printf("请输入你想要实现的功能:\n");printf("1.信息录入\n");printf("2.信息展示\n");printf("3.添加成绩\n");printf("4.删除成绩\n");printf("5.更改成绩\n");printf("6.查找学生\n");printf("7.降序排列\n");printf("0.退出系统\n");scanf ("%d",&menu);return menu;
}
void gn1(struct student *body,int *n)
{printf("请输入需要录入的人数:");scanf("%d",n);for (int i=0;i<*n;i++){printf("请输入第%d同学的学号:",i+1);scanf("%d",&body[i].num);printf("请输入第%d同学的姓名:",i+1);scanf("%s",body[i].name);printf("请输入第%d同学的成绩:",i+1);scanf("%d",&body[i].score);printf("请输入第%d的性别(m/w):",i+1);getchar();scanf("%c",&body[i].sex);printf("请输入第%d同学的电话:",i+1);scanf("%s",body[i].tel);printf("\n");}  printf("录入成功\n");printf("\n");
}void gn2(struct student *body,int *n)
{//信息展示for(int i=0;i<*n;i++){printf("%d/t%s/t%d/t%c/t%s\n",body[i].num,body[i].name,body[i].score,body[i].sex,body[i].tel);}
}void gn3(struct student *body,int *n)
{printf("请输入学生学号:");scanf("%d",&body[*n].num);printf("请输入学生姓名:");scanf("%s",body[*n].name);printf("请输入学生成绩:");scanf("%d",&body[*n].score);printf("请输入的性别(m/w):");getchar();scanf("%c",&body[*n].sex);printf("请输入学生电话:");scanf("%s",body[*n].tel);*n+=1;printf("添加成功\n");
}void gn4(struct student *body,int *n)
{int a;int b=0;//判断是否删除成功printf("请输入学生学号");scanf("%d",&a);for (int i=0;i<*n;i++){if(a==body[i].num){for (int j=i;j<*n-1;j++){body[j]=body[j+1];}(*n)--;b=1;}}if(b){printf("删除成功\n");}else{printf("为查询到该同学\n");}}void gn5(struct student *body,int *n)
{int a=0;//判断是否更改成功char name[20]="";printf("请输入更改电话的学生姓名:");scanf("%s",name);for (int i=0;i<*n;i++){if(strcmp(name,body[i].name)==0){printf("请输入更改后的电话:");scanf("%s",body[i].tel);a=1;}}if(a){printf("更改成功\n");}else{printf("未查询到该学生\n");}}void gn6(struct student *body,int *n)
{//查找学生信息char name[20]="";int a=0;printf("请输入你要查找的学生姓名:");scanf("%s",name);for (int i=0;i<*n;i++){if(strcmp(name,body[i].name)==0){printf("%d\t%s\t%d\t%c\t%s\n",body[i].num,body[i].name,body[i].score,body[i].sex,body[i].tel);a=1;}}if(!a){printf("查询失败\n");}
}
void gn7(struct student *body,int *n)//降序排列
{for (int i=1;i<*n;i++){for (int j=0;j<*n-i;i++){if(body[j].score<body[j+1].score){struct student temp=body[j];body[j]=body[j+1];body[j+1]=temp;}}}printf("排序成功\n");}
#include <luochen.h>
#include "homework.h"
int main(int argc, const char *argv[])
{struct student body[MAX];int num = 0;//定义学生人数while (1){switch(menu()){case 1:{gn1(body,&num);}break;case 2:{gn2(body,&num);}break;case 3:{gn3(body,&num);}break;case 4:{gn4(body,&num);}break;case 5:{gn5(body,&num);}break;case 6:{gn6(body,&num);}break;case 7:{gn7(body,&num);}case 0:exit(0);break;default:printf("输入有误,请重新输入\n");}}return 0;
}
#ifndef HOMEWORK_H
#define HOMEWORK_H
#define MAX 100
struct student
{int num;//记录学号char name[20];//记录名字int score;//记录成绩char sex;//记录性别char tel[11];//记录电话号码
};void gn1(struct student *body,int *n);
int menu();
void gn2(struct student *body,int *n);
void gn3(struct student *body,int *n);
void gn4(struct student *body,int *n);
void gn5(struct student *body,int *n);
void gn6(struct student *body,int *n);
void gn7(struct student *body,int *n);#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/479023.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

44.扫雷第二部分、放置随机的雷,扫雷,炸死或成功 C语言

按照教程打完了。好几个bug都是自己打出来的。比如统计周围8个格子时&#xff0c;有一个各自加号填成了减号。我还以为平移了&#xff0c;一会显示是0一会显示是2。结果单纯的打错了。debug的时候断点放在scanf后面会顺畅一些。中间多放一些变量名方便监视。以及mine要多显示&a…

docker 通过Dockerfile自定义的镜像部署Springboot项目

一、镜像结构介绍&#xff1a; 镜像&#xff1a;层&#xff08;Layer&#xff09;添加安装包、依赖、配置等&#xff0c;每一次操作都形成新的一层&#xff1b;基础镜像&#xff08;BaseImage&#xff09;应用依赖的系统函数库、环境、配置、文件等&#xff1b;入口&#xff0…

全网最早Towards Generalizable Multi-Object Tracking—通用跟踪器的点跟踪CVPR2024

Towards Generalizable Multi-Object Tracking—迈向可推广的多目标跟踪 原标题&#xff1a;Towards Generalizable Multi-Object Tracking 论文链接&#xff1a;https://arxiv.org/pdf/2406.00429 代码链接&#xff1a;https://github.com/qinzheng2000/GeneralTrack.git 作者…

MyBatis框架-动态SQL-XML中的常用标签+特殊字符在XML中的显示

一、if标签、where标签、trim标签、choose标签、set标签、foreach标签 1、问题引入&#xff1a;where关键字和and关键字在动态SQL里面应该如何添加&#xff1f; &#xff08;1&#xff09;if标签&#xff1a; test属性的值是判断条件 if标签里面的内容是条件成立时添加到SQ…

探秘嵌入式位运算:基础与高级技巧

目录 一、位运算基础知识 1.1. 位运算符 1.1.1. 与运算&#xff08;&&#xff09; 1.1.2. 或运算&#xff08;|&#xff09; 1.1.3. 异或运算&#xff08;^&#xff09; 1.1.4. 取反运算&#xff08;~&#xff09; 1.1.5. 双重按位取反运算符&#xff08;~~&#xf…

渗透测试笔记—shodan(7完结)

声明&#xff1a; 学习视频来自B站up主 【泷羽sec】有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&am…

2024年最新版Java八股文复习

最新版本Java八股文复习&#xff0c;每天更新一篇&#xff0c;博主正在持续努力更新中~~~ 一、Java基础篇1、怎么理解面向对象&#xff1f;简单说说封装、继承、多态三大特性&#xff1f;2、多态体现在哪几个方面&#xff1f;3、面向对象的设计原则你知道有哪些吗&#xff1f;4…

Notepad++ 替换所有数字给数字加单引号

前言 今天遇到这样一个场景&#xff1a; 要去更新某张表里 code1,2,3,4,5,6 的数据&#xff0c;把它的 name 设置为 ‘张三’ 但是 code在数据库里面的字段类型是 vachar(64)&#xff0c;它自身携带索引 原本可以这样写 SQL: update tableA set namezhangsan where code in …

前端图像处理(一)

目录 一、上传 1.1、图片转base64 二、图片样式 2.1、图片边框【border-image】 三、Canvas 3.1、把canvas图片上传到服务器 3.2、在canvas中绘制和拖动矩形 3.3、图片(同色区域)点击变色 一、上传 1.1、图片转base64 传统上传&#xff1a; 客户端选择图片&#xf…

推荐一款龙迅HDMI2.0转LVDS芯片 LT6211UX LT6211UXC

龙迅的HDMI2.0转LVDS芯片LT6211UX和LT6211UXC是两款高性能的转换器芯片&#xff0c;它们在功能和应用上有所差异&#xff0c;同时也存在一些共同点。以下是对这两款芯片的详细比较和分析&#xff1a; 一、LT6211UX 主要特性&#xff1a; HDMI2.0至LVDS和MIPI转换器。HDMI2.0输…

51单片机从入门到精通:理论与实践指南入门篇(二)

续51单片机从入门到精通&#xff1a;理论与实践指南&#xff08;一&#xff09;https://blog.csdn.net/speaking_me/article/details/144067372 第一篇总体给大家在&#xff08;全局&#xff09;总体上讲解了一下51单片机&#xff0c;那么接下来几天结束详细讲解&#xff0c;从…

STM32C011开发(3)----Flash操作

STM32C011开发----3.Flash操作 概述硬件准备视频教学样品申请源码下载参考程序生成STM32CUBEMX串口配置堆栈设置串口重定向FLASH数据初始化FLASH 读写演示 概述 STM32C011 系列微控制器内置 Flash 存储器&#xff0c;支持程序存储与数据保存&#xff0c;具备页面擦除、双字写入…

IDEA无法创建java8、11项目创建出的pom.xml为空

主要是由于Spring3.X版本不支持JDK8&#xff0c;JDK11&#xff0c;最低支持JDK17 解决的话要不就换成JDK17以上的版本&#xff0c;但是不太现实 另外可以参考以下方式解决 修改spring初始化服务器地址为阿里云的 https://start.aliyun.com/

【Unity3D】创建自定义字体

前置准备 如图所示&#xff0c;项目工程中需要用文件夹存储0-9的Sprite图片。 使用流程 直接右键存放图片的文件夹&#xff0c;选择【创建自定义字体】&#xff0c;之后会在脚本定义的FontOutputPath中生成材质球和字体。 源码 using System; using System.Collections.Gene…

logminer挖掘日志归档查找问题

--根据发生问题时间点查找归档文件 select first_time,NAME from gv$archived_log where first_time>2016-03-15 17:00:00 and first_time<2016-03-15 21:00:00; 2016-03-15 17:23:55 ARCH/jxdb/archivelog/2016_03_15/thread_1_seq_41588.4060.906577337 2016-03-15 17:…

电商项目高级篇06-缓存

电商项目高级篇06-缓存 1、docker下启动redis2、项目整合redis 缓存 流程图&#xff1a; data cache.load(id);//从缓存加载数据 If(data null){ data db.load(id);//从数据库加载数据 cache.put(id,data);//保存到 cache 中 } return data;在我们的单体项目中可以用Map作…

如何使用GCC手动编译stm32程序

如何不使用任何IDE&#xff08;集成开发环境&#xff09;编译stm32程序? 集成开发环境将编辑器、编译器、链接器、调试器等开发工具集成在一个统一的软件中&#xff0c;使得开发人员可以更加简单、高效地完成软件开发过程。如果我们不使用KEIL,IAR等集成开发环境&#xff0c;…

一个专为云原生环境设计的高性能分布式文件系统

大家好&#xff0c;今天给大家分享一款开源创新的分布式 POSIX 文件系统JuiceFS&#xff0c;旨在解决海量云存储与各类应用平台&#xff08;如大数据、机器学习、人工智能等&#xff09;之间高效对接的问题。 项目介绍 JuiceFS 是一款面向云原生设计的高性能分布式文件系统&am…

Vue-TreeSelect组件最下级隐藏No sub-options

问题&#xff1a;最下级没有数据的话&#xff0c;去除No sub-options信息 为什么没下级&#xff0c;会展示这个&#xff1f; 整个树形结构数据都是由后端构造好返回给前端的。默认子类没数据的话&#xff0c;children是一个空数组。也就是因为这最下级的空数组&#xff0c;导致…

k8s集群增加nfs-subdir-external-provisioner存储类

文章目录 前言一、版本信息二、本机安装nfs组件包三、下载nfs-subdir-external-provisioner配置文件并进行配置1.下载文件2.修改配置 三、进行部署备注&#xff1a;关于镜像无法拉取问题的处理 前言 手里的一台服务器搭建一个单点的k8s集群&#xff0c;然后在本机上使用nfs-su…