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

C语言小项目——通讯录

功能介绍:

1.联系人信息:姓名+年龄+性别+地址+电话

2.通讯录中可以存放100个人的信息

3.功能:

1>增加联系人

2>删除指定联系人

3>查找指定联系人的信息

4>修改指定联系人的信息

5显示所有联系人的信息

6>排序(名字)

  我们将采用模块化设计,分为三个模块:

1. test.c         ———        测试通讯录

2. contact.c   ———        通讯录的声明

3. contact.h    ———       函数的声明

  首先,我们需要一个菜单,以及主函数选择功能的部分。

```test.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>void menu()
{printf("*******************欢迎来到你的通讯录*******************\n");printf("**********1.添加联系人************2.删除联系人**********\n");printf("**********3.查找联系人************4.修改联系人**********\n");printf("**********5.显示联系人************6.联系人排序**********\n");printf("**********0.退出通讯录*********************************\n");printf("*******************欢迎来到你的通讯录*******************\n");
}
int main()
{int input = 0;do {menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:break;case 0:printf("退出通讯录");break;default:printf("选择错误\n");break;}} while (input);return 0;
}
```
  • main函数中,使用do-while循环不断调用menu函数显示菜单,并使用scanf函数获取用户的输入。然后通过switch语句根据用户的输入执行相应的操作,如果输入为0,则输出 “退出通讯录” 并结束程序;如果输入为其他值,则输出 “选择错误”。

那么通讯录中肯定需要人的信息,那么这些人的信息,我们可以把他封装成一个结构体。我们将这些类型信息放进头文件中,在这里我们将它放进已经创建好的contact.h中。

```contact.h
//人的信息
typedef struct Peopleinform
{char name[40];int age;char sex[5];char addr[20];char telephone[20];
}Peopleinform;
```

在这里,我们定义了一个名为Peopleinform的结构体类型,用于存储人员的信息。我们通过使用typedef关键字,可以为这个结构体类型定义一个别名Peopleinform,这样在后续的代码中就可以直接使用Peopleinform来声明该类型的变量,而不需要每次都写完整的struct Peopleinform

我们继续往下写,接下来我们创建通讯录,我们可以声明一个名为data的数组,数组的元素类型为Peopleinform结构体,当然我们在这里必须添加contact.h头文件才能使用它。代码部分如下:

```test.c
#include<stdio.h>
#include"contact.h"
/* --省略void menu部分--*/
int main()
{int input = 0;//创建通讯录Peopleinform data[100];do {menu();printf("请选择:>");scanf("%d", &input);/*-- 省略switch部分 --*/} while (input);return 0;
}
```

 在我们的项目中,自己创建的头文件通常用双引号''"包裹起来,这样我们就可以在.c文件中使用它啦!当然,我们如果把这个通讯录存放人的信息的容量,以及可以显示的当前创建的人的信息封装起来,变成一个结构体。为了方便之后修改我们增加一个预处理器指令#define MAX 100

```contact.h
#define MAX 100
typedef struct Contact
{Peopleinform data[MAX];//存放人的信息的容量int sz;//当前存放信息的个数
}Contact;
```

那么我们如果想在主函数中使用,只需要创建一个名为conContact类型的对象。这样就可以使用con来存储和操作通讯录相关的数据了。接着我们初始化通讯录。并在contact.h头文件中为他声明。

```test.c
int main()
{int input = 0;//创建通讯录Contact con;//创建一个名为con的Contact对象//初始化通讯录InitContact(&con);do {menu();printf("请选择:>");scanf("%d", &input);/*-- 省略switch部分 --*/} while (input);
```
```contact.h
void InitContact(Contact *pc);
```

接下来,contact.c文件终于出场了,由于我们在contact.h头文件声明过void InitContact(Contact *pc); 接下来,我们就可以在contact.c直接使用它。

我们给这个Contact结构体的函数初始化一下:

```contact.c
#include"contact.h"
void InitContact(Contact* pc)
{pc->sz=0;memset(pc->data,0,sizeof(pc->data));
}
```

这里我们选择使用memset函数进行初始化,

(注:memset函数是 C 标准库中的一个函数,定义在<string.h>头文件中。它的作用是将一段内存区域设置为指定的值。函数原型为void *memset(void *s, int c, size_t n),其中s是指向要填充的内存块的指针,c是要设置的值,n是要填充的字节数。) 

紧接着,我们在Switch()语句中,加入我们目前需要的语句,我们现在来写添加联系人模块。

添加联系人模块

```contact.h
//增加联系人
void AddContact(Contact* pc);
```
```contact.c
void AddContact(Contact* pc)
{if (pc->sz == MAX){printf("通讯录已满!无法添加!\n");return;}//增加一个人的信息printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:>");scanf("%s", &pc->data[pc->sz].age);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].telephone);pc->sz++;
}
```

(注:在InitContactAddContact函数中,pc用于访问和修改调用者提供的Contact结构体实例。当调用这些函数时,传递的是Contact结构体变量的地址,函数内部通过这个指针来操作外部传入的结构体。)

pc-sz++; 的作用 

假设 sz 初始值为 5,执行 pc->sz++; 后,sz 的值变为 6 ,表示通讯录中联系人的数量从 5 个增加到了 6 个。 这对于跟踪通讯录中实际存储的联系人数量非常重要,在后续的操作,如显示联系人列表、检查通讯录是否已满等功能中,都依赖这个计数。

 显示联系人模块

显示联系人模块也是一样,我们现将函数声明放在头文件当中,

void ShowContact(const Contact* pc);

然后我们用一个for循环遍历pc->data数组,其中,pc->data数组存储了所有联系人的信息,循环条件i < pc->sz确保只遍历已存储联系人的部分,pc->sz表示当前通讯录中实际存储的联系人数量。

```contact.c
void ShowContact(Contact* pc)
{int i = 0;printf("%s\t%-5s\t%-5s\t%-5s\t%-5s\t\n", "姓名","年齡","性別","地址","電話");for (i = 0; i < pc->sz; i++){printf("%s\t%d\t%s\t%s\t%s\t",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].telephone);}
}
```

这样,我们就基本完成了这个显示联系人的设计啦!那么紧接着,我们如果想要删除这个指定的联系人,该怎么办呢?和上面一样,我们先在头文件中添加一个声明。

void DelContact(Contact* pc);

接着,我们在contact.c文件中去构建这个删除联系人模块,

删除联系人模块

void DelContact(Contact* pc)
{if (pc->sz ==0){printf("无可删除的联系人");return;}//删除//找到要删除的人printf("请输入要删除的人的名字:");scanf("%s", name);int i = 0;int del = 0;for (i = 0; i<pc->sz; i++){if(strcmp(pc->data[i].name,name))==0{del = i;break;}//删除for (i = 0; i < pc->sz; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功");}
}

当我们通讯录里面没有联系人的时候,我们输出“无可删除的联系人”。接着,我们使用 for 循环遍历联系人列表,使用 strcmp 函数比较每个联系人的名字和输入的名字,如果相等则将该元素的索引存储在 del 中并跳出循环。

那么接下来,我们可以发现的是,无论是删除模块、查找模块和修改模块中,我们都需要先找到联系人,才能进行下一步的操作,既然都需要,我们似乎就可以把这个查找部分封装成一个函数,

// 根据姓名查找联系人在数组中的位置,如果找到返回对应索引,未找到返回 -1
int FINDBY_NAME(const Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0) // 比较字符串是否相等{return i; // 找到返回索引}}return -1; // 未找到返回 -1
}

 替换后代码如下:

// 删除联系人的函数
void DelContact(Contact* pc)
{if (pc->sz == 0){printf("没有联系人可删除\n");return;}// 输入要删除的联系人姓名char name[40] = { 0 };printf("请输入要删除的联系人姓名: ");scanf("%s", name);int ret = FINDBY_NAME(pc, name);if (ret == -1){printf("要删除的联系人不存在\n");return;}// 删除操作,将后面的元素依次往前移for (int i = ret; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

我们来看查找联系人模块,

查找联系人模块

void SerContact(const Contact* pc)
{char name[NAME_MAX] = { 0 };printf("请输入要查找人的名字:");scanf("%s",name);int pos = FINDBY_NAME(pc, name);if (-1 == pos){printf("要查找的人不存在\n");return;}//打印信息printf("%s\t%-5s\t%-5s\t%-5s\t%-5s\t\n", "姓名", "年齡", "性別", "地址", "電話");printf("%s\t%-5d\t%-5s\t%-5s\t%-5s\t\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].addr,pc->data[pos].telephone);
}

 我们查找模块,首先输入要查找的联系人姓名,调用 FINDBY_NAME 函数查找该联系人的位置,如果不存在则提示联系人不存在并返回。否则,打印该联系人的详细信息。

紧接着,我们再来看修改联系人,

修改联系人模块

//修改联系人
void ReviContact(Contact* pc)
{char name[NAME_MAX] = { 0 };printf("请输入要修改人的名字:");scanf("%s", name);int pos = FINDBY_NAME(pc, name);if (-1 == pos){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].addr);printf("请输入电话:>");scanf("%s", pc->data[pos].telephone);printf("修改完成\n");
}

我们想要修改联系人,首先肯定需要找到这个联系人,所以我们首先要查找,输入要修改的联系人姓名,调用FINDBY_NAME函数可以查找该联系人的位置,如果不存在则提示联系人不存在并返回。否则,依次输入新的联系人信息。

排序联系人模块

最后一个模块,就是对这些联系人进行排序,这里使用使用冒泡排序算法,比较相邻联系人的姓名,如果前一个联系人的姓名大于后一个联系人的姓名,则交换它们的位置。

// 排序联系人(按姓名升序排序)
void SortContact(Contact* pc)
{int i, j;Peopleinform temp;for (i = 0; i < pc->sz - 1; i++){for (j = 0; j < pc->sz - i - 1; j++){if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0){temp = pc->data[j];pc->data[j] = pc->data[j + 1];pc->data[j + 1] = temp;}}}printf("联系人已按姓名排序\n");
}

strcmp 是 C 语言标准库 <string.h> 中的一个字符串比较函数,用于比较两个字符串的大小。

函数原型int strcmp(const char *str1, const char *str2);

在 SortContact 函数中,strcmp(pc->data[j].name, pc->data[j + 1].name) > 0 表示如果 pc->data[j].name 这个字符串在字典序上大于 pc->data[j + 1].name 这个字符串,就交换这两个联系人的信息,从而实现按姓名排序的功能。

源代码如下:

```contact.h
#pragma once
#include<stdio.h>
#include<string.h>
#define MAX 100
#define NAME_MAX 40  // 定义 NAME_MAX 的大小
// 个人信息
typedef struct Peopleinform
{char name[40];int age;char sex[5];char addr[20];char telephone[20];
}Peopleinform;
typedef struct Contact
{Peopleinform data[MAX];// 存储个人信息的数组int sz;// 当前存储信息的数量
}Contact;// 初始化通讯录
void InitContact(Contact* pc);
// 添加联系人
void AddContact(Contact* pc);
// 删除联系人
void DelContact(Contact* pc);
// 查找联系人
void SerContact(const Contact* pc);
// 修改联系人
void ReviContact(Contact* pc);
// 排序联系人
void SortContact(Contact* pc);
// 显示联系人
void ShowContact(const Contact* pc);
```
```contact.c
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}
void AddContact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == MAX){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].addr);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].telephone);pc->sz++;
}// 根据姓名查找联系人在数组中的位置,如果找到返回对应索引,未找到返回 -1
int FINDBY_NAME(const Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0) // 比较字符串是否相等{return i; // 找到返回索引}}return -1; // 未找到返回 -1
}// 删除联系人的函数
void DelContact(Contact* pc)
{if (pc->sz == 0){printf("没有联系人可删除\n");return;}// 输入要删除的联系人姓名char name[40] = { 0 };printf("请输入要删除的联系人姓名: ");scanf("%s", name);int ret = FINDBY_NAME(pc, name);if (ret == -1){printf("要删除的联系人不存在\n");return;}// 删除操作,将后面的元素依次往前移for (int i = ret; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}
//查找联系人
void SerContact(const Contact* pc)
{char name[NAME_MAX] = { 0 };printf("请输入要查找人的名字:");scanf("%s",name);int pos = FINDBY_NAME(pc, name);if (-1 == pos){printf("要查找的人不存在\n");return;}//打印信息printf("%s\t%-5s\t%-5s\t%-5s\t%-5s\t\n", "姓名", "年齡", "性別", "地址", "電話");printf("%s\t%-5d\t%-5s\t%-5s\t%-5s\t\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].addr,pc->data[pos].telephone);
}
//修改联系人
void ReviContact(Contact* pc)
{char name[NAME_MAX] = { 0 };printf("请输入要修改人的名字:");scanf("%s", name);int pos = FINDBY_NAME(pc, name);if (-1 == pos){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].addr);printf("请输入电话:>");scanf("%s", pc->data[pos].telephone);printf("修改完成\n");
}
// 排序联系人(按姓名升序排序)
void SortContact(Contact* pc)
{int i, j;Peopleinform temp;for (i = 0; i < pc->sz - 1; i++){for (j = 0; j < pc->sz - i - 1; j++){if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0){temp = pc->data[j];pc->data[j] = pc->data[j + 1];pc->data[j + 1] = temp;}}}printf("联系人已按姓名排序\n");
}// 显示所有联系人信息的函数
void ShowContact(const Contact* pc)
{int i = 0;printf("%s\t%-5s\t%-5s\t%-5s\t%-5s\t\n", "姓名", "年龄", "性别", "地址", "电话");for (i = 0; i < pc->sz; i++){printf("%s\t%d\t%s\t%s\t%s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].telephone);}
}
```
```test.c
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"void menu()
{printf("*******************欢迎来到你的通讯录*******************\n");printf("**********1.添加联系人************2.删除联系人**********\n");printf("**********3.查找联系人************4.修改联系人**********\n");printf("**********5.显示联系人************6.联系人排序**********\n");printf("**********0.退出通讯录**********************************\n");printf("*******************欢迎来到你的通讯录*******************\n");
}
int main()
{int input = 0;//创建通讯录Contact con;//创建一个名为con的Contact对象//初始化通讯录InitContact(&con);do {menu();printf("请选择:>");if (scanf("%d", &input) != 1) {// 处理输入错误的情况,例如提示用户重新输入printf("输入错误,请重新输入\n");// 清空输入缓冲区while (getchar() != '\n');continue;}switch (input){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:SerContact(&con);break;case 4:ReviContact(&con);break;case 5:ShowContact(&con);break;case 6:SortContact(&con);case 0:printf("退出通讯录");break;default:printf("选择错误\n");break;}} while (input!=0);
}
```

相关文章:

C语言小项目——通讯录

功能介绍&#xff1a; 1.联系人信息&#xff1a;姓名年龄性别地址电话 2.通讯录中可以存放100个人的信息 3.功能&#xff1a; 1>增加联系人 2>删除指定联系人 3>查找指定联系人的信息 4>修改指定联系人的信息 5显示所有联系人的信息 6>排序&#xff08;名字&…...

uni-app连接EventSource

前言 uniapp默认是不支持event-source&#xff0c;这里是借助renderjs进行SSE连接 正文 引入event-source-polyfill 这里演示的是直接将代码下载到本地进行引入 下载地址 把里面的eventsource.min.js文件放到项目中的static文件夹 项目封装event-source.vue组件 <templ…...

Spring Boot 实战:轻松实现文件上传与下载功能

目录 一、引言 二、Spring Boot 文件上传基础 &#xff08;一&#xff09;依赖引入 &#xff08;二&#xff09;配置文件设置 &#xff08;三&#xff09;文件上传接口编写 &#xff08;一&#xff09;文件类型限制 &#xff08;二&#xff09;文件大小验证 &#xff0…...

火狐浏览器Firefox一些配置

没想到还会开这个…都是Ubuntu的错 一些个人习惯吧 标签页设置 常规-标签页 1.按最近使用顺序切换标签页 2.打开新标签而非新窗口&#xff08;讨厌好多窗口&#xff09; 3.打开新链接不直接切换过去&#xff08;很打断思路诶&#xff09; 4.关闭多个标签页时不向我确认 启动…...

[STM32 HAL库]串口中断编程思路

一、前言 最近在准备蓝桥杯比赛&#xff08;嵌入式赛道&#xff09;&#xff0c;研究了以下串口空闲中断DMA接收不定长的数据&#xff0c;感觉这个方法的接收效率很高&#xff0c;十分好用。方法配置都成功了&#xff0c;但是有一个点需要进行考虑&#xff0c;就是一般我们需要…...

C++入门 详细版

欢迎来到干货小仓库&#xff01;&#xff01; 一分耕耘一分收获&#xff0c;离自己的目标越来越近。 passion&#xff01;passion&#xff01;&#xff01;passion&#xff01;&#xff01;&#xff01; 1.命名空间 由于C语言无法避免名字或者函数重复等问题&#xff0c;当有多…...

MIAOYUN信创云原生项目亮相西部“中试”生态对接活动

近日&#xff0c;以“构建‘中试’生态&#xff0c;赋能科技成果转化”为主题的“科创天府智汇蓉城”西部“中试”生态对接活动在成都高新区菁蓉汇隆重开幕。活动分为成果展览、“中试”生态主场以及成果路演洽谈对接三大板块。在成果展览环节&#xff0c;成都元来云志科技有限…...

网络编程 | UDP组播通信

1、什么是组播 在上一篇博客中&#xff0c;对UDP的广播通信进行了由浅入深的总结梳理&#xff0c;本文继续对UDP的知识体系进行探讨&#xff0c;旨在将UDP的组播通信由浅入深的讲解清楚。 组播是介于单播与广播之间&#xff0c;在一个局域网内&#xff0c;将某些主机添加到组中…...

T-SQL语言的语法

T-SQL深度解析与应用 T-SQL&#xff08;Transact-SQL&#xff09;是微软SQL Server使用的一种扩展SQL&#xff08;结构化查询语言&#xff09;。它不仅支持标准SQL的所有功能&#xff0c;而且增加了许多实用的扩展和特性&#xff0c;使得数据库的操作更加灵活和强大。本文将对…...

Java开发提效秘籍:巧用Apache Commons IO工具库

一、引言 在 Java 开发的广袤领域中&#xff0c;输入输出&#xff08;I/O&#xff09;操作宛如一座桥梁&#xff0c;连接着程序与外部世界&#xff0c;从文件的读取与写入&#xff0c;到网络数据的传输&#xff0c;I/O 操作无处不在&#xff0c;其重要性不言而喻。然而&#xf…...

第1章:Python TDD基础与乘法功能测试

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

web前端1--基础

&#xff08;时隔数月我又来写笔记啦~&#xff09; 1、下载vscode 1、官网下载&#xff1a;Visual Studio Code - Code Editing. Redefined 2、步骤&#xff1a; 1、点击同意 一直下一步 勾一个创建桌面快捷方式 在一直下一步 2、在桌面新建文件夹 拖到vscode图标上 打开v…...

.Net Core微服务入门全纪录(五)——Ocelot-API网关(下)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…...

2024嵌入式系统的未来发展与技术洞察分享

时间如白驹过隙&#xff0c;不知不觉又是一年&#xff0c;这一年收获满满。接下来&#xff0c;将本年度对技术的感悟和洞察分析如下&#xff0c;希望对大家有所帮助。 在过去几十年里&#xff0c;嵌入式系统技术迅速发展&#xff0c;成为现代电子设备和智能硬件的核心组成部分。…...

python-44-嵌入式数据库SQLite和DuckDB

文章目录 1 SQLite1.1 世界上最流行的数据库1.1 SQLite简介1.2 插入语句1.3 查询数据1.4 更新数据1.5 删除数据2 DuckDB2.1 DuckDB简介2.2 DuckDB与Python结合使用2.2.1 创建表2.2.2 分析语句2.2.3 导出为parquet文件2.3 Windows中使用DuckDB3 参考附录1 SQLite Python的一个特…...

1.2.神经网络基础

目录 1.2.神经网络基础 1.2.1.Logistic回归 1.2.2 梯度下降算法 1.2.3 导数 1.2.4 向量化编程 1.2.5 正向传播与反向传播 1.2.6.练习 1.2.神经网络基础 1.2.1.Logistic回归 1.2.1.1.Logistic回归 逻辑回归是一个主要用于二分分类类的算法。那么逻辑回归是给定一个x ,…...

算法题目总结-双指针

文章目录 1.滑动窗口类型1.长度最小的子数组1.答案2.思路 2.无重复字符的最长子串1.答案2.思路 2.双指针类型1.盛最多水的容器1.答案2.思路 2.三数之和1.答案2.思路 1.滑动窗口类型 1.长度最小的子数组 1.答案 package com.sunxiansheng.arithmetic.day10;/*** Description:…...

人形机器人将制造iPhone!

前言 优必选机器人和富士康通过一项突破性的合作伙伴关系&#xff0c;正在将先进的人形机器人&#xff08;如Walker S1及其升级版Walker S2&#xff09;整合到制造流程中&#xff0c;以改变iPhone的生产方式。这一合作旨在通过提升机器人能力、优化工作流程以及实现更智能的自动…...

redis 各个模式的安装

一、Redis单机安装 1、安装gcc依赖 Redis是C语言编写的&#xff0c;编译需要GCC。 Redis6.x.x版本支持了多线程&#xff0c;需要gcc的版本大于4.9&#xff0c;但是CentOS7的默认版本是4.8.5。 升级gcc版本&#xff1a; yum -y install centos-release-scl yum -y install d…...

《王者荣耀》皮肤爬虫源码

1.爬取网页 https://pvp.qq.com/web201605/herolist.shtml 2.python代码 import requests from bs4 import BeautifulSoup import os import threading from queue import Queuedef mul(x):if not os.path.exists(x):os.mkdir(x)print("目录创建成功")else:pass h…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...