当前位置: 首页 > news >正文

静态通讯录,适合初学者的手把手一条龙讲解

数据结构的顺序表和链表是一个比较困难的点,初见会让我们觉得有点困难,正巧C语言中有一个类似于顺序表和链表的小程序——通讯录。我们今天就来讲一讲通讯录的实现,也有利于之后顺序表和链表的学习。

目录

0.通讯录的初始化 

1.菜单的创建

2.主函数的创建

3.定义联系人内容(结构体)

4.定义通讯录内容(结构体)

5.避免代码冗余而定义的查找函数

6.删除联系人信息

7.修改通讯录信息

8.显示某一个人的信息

9.整个通讯录的打印

10.将通讯录按名字排序

11.全部代码

我们需要用C语言模拟一个通讯录可以用来存储100个人的信息

每个人的信息包括:

姓名、电话、性别、住址、年龄

功能包括:

  1. 新增联系人
  2. 查找联系人
  3. 删除联系人
  4. 修改联系人
  5. 查看所有联系人
  6. 以名字排序所有联系人 

0.通讯录的初始化 

尽管我们这是一个基础的通讯录,它并不具备保存功能,但是我们应该让它拥有一个初始化功能。

void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}

1.菜单的创建

首先要有一个一目了然的菜单。

要实现这么多的功能,我们首先想到了switch语句,用case表示不同的情况。

不过考虑到case 1,case 2这样的写法不容易读懂,代码的可维护性也不高。

我们在这里定义一个枚举类型。

enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};

 如图所示,枚举类型在我们没有额外操作的情况下,里面的元素是从零开始

这样一来,我们就可以从case 1这样的写法变成 case ADD,一目了然,一看就能看懂。

我们也需要打印选项,另外定义一个menu函数:

void menu()
{printf("'****************************************\n");printf("'**********   1.add     2.del   *********\n");printf("'**********   3.search  4.modify ********\n");printf("'**********   5.show    6.sort   ********\n");printf("'**********   0.exit             ********\n");printf("'****************************************\n");
}

2.主函数的创建

当要实现某一个函数功能时,我们直接在case语句后调用此函数便可。

int main()
{int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch(input){case ADD:break;case DEL:break;case SEARCH:break;case MODIFY:break;case SHOW:break;case SORT:break;case EXIT:printf("退出");break;default:break;}} while (input);return 0;
}

缺少的东西我们待会再补上。

3.定义联系人内容(结构体)

一个人的信息包括很多方面,要录入的话还是用结构体比较方便。

我们定义姓名,年龄,性别,电话和地址五个变量,并将其重命名为PeoInfo。

typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;

4.定义通讯录内容(结构体)

typedef struct Contact
{PeoInfo data[MAX];int sz;
}Contact;

 我们要在什么位置插入一个元素呢?

我们知道,下标是从0开始的。

当我们插入一个数据时,我们实际上是插入在我们所定义的sz的位置。

举个例子。

当sz为5时,我们已经插入了下标为0,1,2,3,4的五个元素。

这时如果要插入新元素的话,就是在下标为5的地方插入,也就是插入到sz的位置。

但是我们并没有在sz的位置分配空间,所以我们在输入之后,需要将sz加一来分配空间。

void AddContact(Contact* pc)
{if (pc->sz == 100){printf("通讯录已满\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:>");scanf("%d", &pc->data[pc->sz].age);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("添加成功\n");
}

需要注意的是,当空间已满时,要返回,这时就不要往里面硬加了。

5.避免代码冗余而定义的查找函数

在接下来的修改或者删除函数里面,我们将会需要查找所要删除或者修改的人的名字这样的一个功能,为了避免冗余,我们不是在用到时再写一遍,而是定义一个函数,在用到它的时候直接调用,这就方便了许多。

int FindByName(Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;break;}}return -1;
}

当查找到要查找到名字时,返回这个位置的下标,没有找到则返回-1。

6.删除联系人信息

要删除一个人的信息,首先需要输入这个人的名字并查找它的位置,这时上面的代码就派上用场了。

我们先调用函数找到这个人的信息,然后调用它的返回值,也就是目标联系人的下标,并用这个下标来修改。

修改的方式是经典的后一个覆盖前一个,不过由于下标是元素个数再减一,为了避免溢出,我们需要是将sz减一。

void DelContact(Contact* pc)
{char name[MAX_NAME];if (pc->sz == 0){printf("通讯录已满\n");return;}printf("输入要删除的人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}for (int i = pos; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");}

同样的,在通讯录元素已满时,返回。

7.修改通讯录信息

首先查找,当查找到时,我们只需利用它的下标,来将此位置的信息进行重新录入即可。

void ModifyContact(Contact* pc)
{printf("输入要修改的人的名字:>");char name[12] = { 0 };scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("此人不存在\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pos].name);printf("请输入年龄:>");scanf("%d", &pc->data[pos].age);printf("请输入性别:>");scanf("%s", pc->data[pos].sex);printf("请输入电话:>");scanf("%s", pc->data[pos].tele);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("修改成功\n");
}

8.显示某一个人的信息

我们调用上面的查找函数 ,找到就用返回值下标打印出来就行。

int SearchContact(Contact* pc)
{char name[12] = { 0 };printf("请输入要查找的人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("此人信息不存在\n");} printf("此人信息如下:\n");printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-10s %-4d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);return pos;
}

9.整个通讯录的打印

我们调用sz,来将每一个人的信息打印出来。

void ShowContact(Contact* pc)
{int i = 0;printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-30s\n",  pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}

10.将通讯录按名字排序

qsort函数可以很好的实现这个问题。

1.首元素地址base
我们要排序一组数据,首先我们需要找到这组数据在哪,因此我们直接将首元素的地址传给qsort函数来确定从哪开始排序。

2.元素个数num
我们知道了从哪开始,也要知道在哪结束才能确定一组需要排序的数据,但是我们不方便直接将结尾元素的地址传入函数,因此我们将需要排序的元素的个数传给qsort函数来确定一组数据。

3.元素大小size
我们知道qsort函数能排序任意数据类型的一组数据,因此我们用void*类型的指针来接收元素,但是我们知道void*类型的指针不能进行加减操作,也就无法移动,那么在函数内部我们究竟用什么类型的指针来操作变量呢?我们可以将void*类型的指针强制类型转换成char*类型的指针后来操作元素,因为char*类型的指针移动的单位字节长度是1个字节,我们只需要再知道我们需要操作的数据是几个字节就可以操作指针从一个元素移动到下一个元素,因此我们需要将元素大小传入qsort函数。

4.自定义比较函数compare

我们需要告诉qsort函数我们希望数据按照怎么的方式进行比较,比如对于几个字符串,我们可以比较字符串的大小。代码如下,我们想要传入什么类型的参数,就要将其强制类型转换成什么类型,并且返回一个int值。

int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}

然后就是qsort函数的调用了:

void SortContact(Contact* pc)
{qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);
}

11.全部代码

下面是全部的代码,定义两个源文件和一个头文件。

//contact.h部分
#pragma once
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;
typedef struct Contact
{PeoInfo data[MAX];int sz;
}Contact;
void InitContact(Contact* pc);
void AddContact(Contact* pc);
void DelContact(Contact* pc);
void SortContact(Contact* pc);
int SearchContact(Contact* pc);
void ModifyContact(Contact* pc); 
void ShowContact(Contact* pc);
int FindByName(Contact* pc, char name[]);
//contact.c
#include"contact.h"
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}
void AddContact(Contact* pc)
{if (pc->sz == 100){printf("通讯录已满\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:>");scanf("%d", &pc->data[pc->sz].age);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("添加成功\n");
}
void DelContact(Contact* pc)
{char name[MAX_NAME];if (pc->sz == 0){printf("通讯录已满\n");return;}printf("输入要删除的人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}for (int i = pos; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");}
int FindByName(Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;break;}}return -1;
}
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
int SearchContact(Contact* pc)
{char name[12] = { 0 };printf("请输入要查找的人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("此人信息不存在\n");} printf("此人信息如下:\n");printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-10s %-4d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tele, pc->data[pos].addr);return pos;
}
void ShowContact(Contact* pc)
{int i = 0;printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-30s\n",  pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}
void ModifyContact(Contact* pc)
{printf("输入要修改的人的名字:>");char name[12] = { 0 };scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("此人不存在\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pos].name);printf("请输入年龄:>");scanf("%d", &pc->data[pos].age);printf("请输入性别:>");scanf("%s", pc->data[pos].sex);printf("请输入电话:>");scanf("%s", pc->data[pos].tele);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("修改成功\n");
}
void SortContact(Contact* pc)
{qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);
}
//test.c
#include"contact.h"
void menu()
{printf("'****************************************\n");printf("'**********   1.add     2.del   *********\n");printf("'**********   3.search  4.modify ********\n");printf("'**********   5.show    6.sort   ********\n");printf("'**********   0.exit             ********\n");printf("'****************************************\n");
}
enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
int main()
{int input = 0;Contact con;InitContact(&con);do{menu();printf("请选择:>");scanf("%d", &input);switch(input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SEARCH:SearchContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case SORT:SortContact(&con);break;case EXIT:printf("退出");break;default:printf("输入错误\n");break;}} while (input);return 0;
}

这篇博客旨在总结我自己阶段性的学习,要是能帮助到大家,那可真是三生有幸!😀如果觉得我写的不错的话还请点个赞和关注哦~我会持续输出编程的知识的!🌞🌞🌞  

相关文章:

静态通讯录,适合初学者的手把手一条龙讲解

数据结构的顺序表和链表是一个比较困难的点&#xff0c;初见会让我们觉得有点困难&#xff0c;正巧C语言中有一个类似于顺序表和链表的小程序——通讯录。我们今天就来讲一讲通讯录的实现&#xff0c;也有利于之后顺序表和链表的学习。 目录 0.通讯录的初始化 1.菜单的创建…...

【你不知道的 CSS】你写的 CSS 太过冗余,以至于我对它下手了

:is() 你是否曾经写过下方这样冗余的CSS选择器: .active a, .active button, .active label {color: steelblue; }其实上面这段代码可以这样写&#xff1a; .active :is(a, button, label) {color: steelblue; }看~是不是简洁了很多&#xff01; 是的&#xff0c;你可以使用…...

Lesson 8.1 决策树的核心思想与建模流程

文章目录一、借助逻辑回归构建决策树1. 决策树实例2. 决策树知识补充2.1 决策树简单构建2.2 决策树的分类过程2.3 决策树模型本质2.4 决策树的树生长过程2.5 树模型的基本结构二、决策树的分类与流派1. ID3(Iterative Dichotomiser 3) 、C4.5、C5.0 决策树2. CART 决策树3. CHA…...

【算法】FIFO先来先淘汰算法分析和编码实战

背景 在设计一个系统的时候&#xff0c;由于数据库的读取速度远小于内存的读取速度 为加快读取速度&#xff0c;将一部分数据放到内存中称为缓存&#xff0c;但内存容量是有限的&#xff0c;当要缓存的数据超出容量&#xff0c;就需要删除部分数据 这时候需要设计一种淘汰机制…...

二分查找——我欲修仙(功法篇)

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️我欲修仙】 学习名言&#xff1a;临渊羡鱼,不如退而结网——《汉书董仲舒传》 系列文章目录 第一章 ❤️ 二分查找 文章目录系列文章目录前言&#x1f697;&#x1f697;&#x1f697;二分查找&…...

Python 多线程

文章目录一、简介1.1 多线程的特性1.2 GIL二、线程1.2 单线程1.3 多线程三、线程池3.1 pool.submit3.2 pool.map四、Lock&#xff08;线程锁&#xff09;4.1 无锁导致的线程资源异常4.2 有锁五、Event&#xff08;事件&#xff09;5.1 简介5.2 示例六、Queue&#xff08;队列&a…...

JVM笔记(九)选择合适的垃圾收集器

Epsilon收集器Epsilon收集器由RedHat公司在JEP 318中提出&#xff0c;在此提案里Epsilon被形容成一个无操作的收集器&#xff08;A No-Op Garbage Collector&#xff09;&#xff0c;而事实上只要Java虚拟机能够工作&#xff0c;垃圾收集器便不可能是真正“无操作”的。原因是“…...

二维图像处理到三维点云处理

一、Opencv和PCL 下面是opencv和pcl的特点、区别和联系的详细对比表格。 特点/区别/联系OpenCVPCL英文全称Open Source Computer Vision LibraryPoint Cloud Library语言C、Python、JavaC功能图像处理(图像处理和分析、特征提取和描述、图像识别和分类、目标检测和跟踪等)、计…...

leetcode 删除有序数组中的重复项

题目 给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。 由于在某些语言中不能改变数组的长度&#xff0c;所以必须将结果放在数组nums的第一…...

JVM学习.03 类加载机制

1、前言从事Java开发工作的都知道&#xff0c;Java程序提交到JVM运行时&#xff0c;需要编译成Class文件&#xff0c;才能被JVM加载运行。那么这些Class文件进入到虚拟机后会发生什么&#xff1f;以及Class是如何被加载的&#xff1f;这些都是本文要讲解的部分。2、类加载时机所…...

Celery使用:优秀的python异步任务框架

目录Celery 简介介绍安装基本使用Flask使用Celery异步任务定时任务Celery使用Flask上下文进阶使用参考停止Worker后台运行Celery 简介 介绍 Celery 是一个简单、灵活且可靠的&#xff0c;处理大量消息的分布式系统&#xff0c;并且提供维护这样一个系统的必需工具。 它是一个…...

第十四届蓝桥杯三月真题刷题训练——第 19 天

第 1 题&#xff1a;灌溉_BFS板子题 题目描述 小蓝负责花园的灌溉工作。 花园可以看成一个 n 行 m 列的方格图形。中间有一部分位置上安装有出水管。 小蓝可以控制一个按钮同时打开所有的出水管&#xff0c;打开时&#xff0c;有出水管的位置可以被认为已经灌溉好。 每经过一分…...

类和对象 - 下

本文已收录至《C语言》专栏&#xff01; 作者&#xff1a;ARMCSKGT 目录 前言 正文 初始化列表 成员变量的定义与初始化 初始化列表的使用 变量定义顺序 explicit关键字 隐式类型转换 自定义类型隐式转换 explicit 限制转换 关于static static声明类成员 友元 友…...

【云原生】Linux基础IO(文件理解与操作)

✨个人主页&#xff1a; Yohifo &#x1f389;所属专栏&#xff1a; Linux学习之旅 &#x1f38a;每篇一句&#xff1a; 图片来源 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 Great minds discuss ideas. Average minds discuss events. Small minds disc…...

CentOS 7 安装 mysql 8.0 客户端

只想安装 mysql-client 8.0 &#xff0c; 结果发现直接 yum install mysql mysql-client 安装的版本是 mysql Ver 15.1 Distrib 5.5.68-MariaDB &#xff0c;这个版本太低&#xff0c;连接其他服务器上的 mysql 8.0 时总是失败&#xff0c;因为 mysql 8.0 加密方式改变了&#…...

Ubuntu下载、配置、安装和编译opencv

1 安装相关依赖安装opencv前&#xff0c;需要先准备好编译器、相关依赖sudo apt-get install gcc g cmake vim sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev sudo apt-get install libgtk2.0-…...

第七讲 贪心

文章目录股票买卖 II货仓选址&#xff08;贪心:排序中位数&#xff09;糖果传递&#xff08;❗贪心&#xff1a;中位数&#xff09;雷达设备&#xff08;贪心排序&#xff09;付账问题&#xff08;平均值排序❓&#xff09;乘积最大&#xff08;排序/双指针&#xff09;后缀表达…...

数字藏品的未来及发展趋势

随着互联网的普及以及数字文化的日益发展&#xff0c;数字藏品作为一种全新的收藏方式正在逐步兴起。数字藏品可以是数字版权、数字艺术品、数字音乐以及数字视频等形式&#xff0c;这些藏品通过数字化技术保存下来&#xff0c;并在互联网上进行传播和交易。数字藏品的发展趋势…...

值得记忆的STL常用算法,分分钟摆脱容器调用的困境,以vector为例,其余容器写法类似

STL常用算法 概述&#xff1a; 算法主要是由头文件<algorithm> <functional> <numeric>组成 <algorithm>是所有STL头文件中最大的一个&#xff0c;范围涉及到比较、交换、查找、遍历操作、复制、修改等等 <nuneric>体积很小&#xff0c;只包括…...

java如何手动导jar包

今天用IDEA&#xff0c;需要导入一个Jar包&#xff0c;因为以前都是用eclipse的&#xff0c;所以对这个idea还不怎么上手&#xff0c;连打个Jar包都是谷歌了一下。 但是发现网上谷歌到的做法一般都是去File –> Project Structure中去设置&#xff0c;有没有如同eclipse一样…...

怎么防止SQL注入?

首先SQL注入是一种常见的安全漏洞&#xff0c;黑客可以通过注入恶意代码来攻击数据库和应用程序。以下是一些防止SQL注入的基本措施&#xff1a; 数据库操作层面 使用参数化查询&#xff1a;参数化查询可以防止SQL注入&#xff0c;因为参数化查询会对用户输入的数据进行过滤和…...

【千题案例】TypeScript获取两点之间的距离 | 中点 | 补点 | 向量 | 角度

我们在编写一些瞄准、绘制、擦除等功能函数时&#xff0c;经常会遇到计算两点之间的一些参数&#xff0c;那本篇文章就来讲一下两点之间的一系列参数计算。 目录 1️⃣ 两点之间的距离 ①实现原理 ②代码实现及结果 2️⃣两点之间的中点 ①实现原理 ②代码实现及结果 3…...

堆叠注入--攻防世界CTF赛题学习

在一次联系CTF赛题中才了解到堆叠注入&#xff0c;在这里简单介绍一下。 堆叠注入的原理什么的一搜一大堆&#xff0c;我就不引用百度了&#xff0c;直接进入正题。 这个是攻防世界的一道CTF赛题。 采用寻常思路来寻找sql注入漏洞。 payload:1 and 11-- 利用payload: and 12…...

STM32 ADC+定时器+DMA+FFT

本次实现的功能为单片机DAC输出一个正弦波&#xff0c;然后ADC定时采样用DMA输出&#xff0c;最后对DAC输出的波形进行FFT。单片机STM32F103ZET6内部时钟一、配置ADCADC端口为PA1&#xff0c;采用DMA输出&#xff0c;定时器3触发定时器时钟64M&#xff0c;分频后为102.4KHzADC采…...

用Node.js实现一个HTTP服务器程序(文件服务器)

http Node.js开发的目的就是为了用JavaScript编写Web服务器程序。因为JavaScript实际上已经统治了浏览器端的脚本,其优势就是有世界上数量最多的前端开发人员。如果已经掌握了JavaScript前端开发,再学习一下如何将JavaScript应用在后端开发,就是名副其实的全栈了。 HTTP协…...

Python实现人脸识别检测, 对美女主播照片进行评分排名

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 素材、视频、代码、插件安装教程我都准备好了&#xff0c;直接在文末名片自取就可点击此处跳转 开发环境: Python 3.8 Pycharm 2021.2 模块使用&#xff1a; requests >>> pip install requests tqdm >…...

【数据结构与算法】什么是双向链表?并用代码手动实现一个双向链表

文章目录一、什么是双向链表二、双向链表的简单实现一、什么是双向链表 我们来看一下这个例子&#xff1a; 在一个教室里&#xff0c;所有的课桌排成一列&#xff0c;如图 相信在你们的读书生涯中&#xff0c;老师肯定有要求你们记住自己的前后桌是谁。所以该例子中&#x…...

23种设计模式

参考链接&#xff1a; 【狂神说Java】通俗易懂的23种设计模式教学&#xff08;停更&#xff09;_哔哩哔哩_bilibili 23种设计模式【狂神说】_狂神说设计模式_miss_you1213的博客-CSDN博客 1. 单例模式 参考链接&#xff1a; 【狂神说Java】单例模式-23种设计模式系列_哔哩哔哩…...

20美刀一个月的ChatGPT架构师,性价比逆天了

文章目录20美刀一个月的ChatGPT架构师&#xff0c;性价比逆天了1.角色设定2.基本描述3.解决方案4.物理网络蓝图5.系统集成接口5.1 系统集成接口设计5.1.1 前端服务器与后端服务器接口&#xff1a;5.1.2 后端服务器与去背景处理服务接口&#xff1a;5.2 系统集成接口展示6.部署环…...

海门区教育科学规划课题2020年度成果鉴定书

海门区教育科学规划课题2020年度成果鉴定书 课题编号&#xff1a;HMGZ2020007 课题名称 中学历史核心素养校本化实施的培育研究 主持人 徐彬 工作单位 南通市海门证大中学 核心组成员 &#xff08;包括主持人&#xff09; 姓名 研究任务完成情况 &#xff08;获得的主要成果、…...

天堂网长尾关键词挖掘网站/全球最大的中文搜索引擎

1、安装 Yum install -y freeradius freeradius-mysql freeradius-utils 2、配置 1&#xff09;修改 clients.conf # vi /usr/local/etc/raddb/clients.conf 在最后增加如下几行&#xff1a; client 172.18.5.88 { 增加认证体&#xff0c;填写OMA的ip地址 s…...

web网站开发自学指南/外链图片

一、基础知识 然后编译设备树&#xff0c; make dtbs sudo cp arch/arm/boot/dts/imx6ull-alientek-nand.dtb /home/zys/linux/tftpboot/ -f 然后以新的设备树启动linux 查看/sys/bus/i2c/devices下 会有地址为1e的设备&#xff0c;就是我们刚刚添加的设备 二、驱动编写 #i…...

昆明小程序开发联系方式/莱阳seo排名

txt文件小 #coding:utf-8fname为所读xx.txt文件 输出为&#xff1a;文件第一行和最后一行 fname test.txt with open(fname, r) as f: #打开文件 lines f.readlines() #读取所有行 first_line lines[0] #取第一行 last_line lines[-1] #取最后一行 print 文件 fname 第一…...

医院网站建设招标说明/韶关新闻最新今日头条

最近&#xff0c;小米充电宝突然不能正常输出也不能充电了。具体现象是充电时四个灯同时闪烁&#xff0c;平时既也不能输出供电&#xff0c;也充不进电&#xff0c;但是电池电量显示正常。 小米充电宝很好拆&#xff0c;无聊拆开看看也行哦。中午花了半小时把充电宝修好了。 …...

中企动力网站建设方案/系统优化app最新版

存储字符集 utf8 和 utf8mb4 utf8 是 Mysql 中的一种字符集&#xff0c;只支持最长三个字节的 UTF-8 字符&#xff0c;也就是 Unicode 中的基本多文本平面。 要在 Mysql 中保存 4 字节长度的 UTF-8 字符&#xff0c;需要使用 utf8mb4 字符集&#xff0c;但只有 5.5.3 版本以后…...

网页制作工具的英文名/牛排seo

欢迎订阅我的新专栏《现代命令行工具指南》&#xff0c;精讲目前最流行的开源命令行工具&#xff0c;大大提升你的工作效率。 每个测试人员都知道保障需求质量非常重要&#xff0c;那到底为什么这么重要&#xff1f;又如何来保障需求质量呢&#xff1f;如果要回答好这些问题&am…...