【C语言实战项目】通讯录

一.了解项目功能

在本次实战项目中我们的目标是实现一个通讯录:

该通讯录可以用来存储1000个人的信息

每个人的信息包括:姓名年龄性别住址电话

通讯录提供功能有:

  1. 添加联系人信息
  2. 删除指定联系人信息
  3. 查找指定联系人信息
  4. 修改指定联系人信息
  5. 显示所有联系人信息
  6. 清空所有联系人
  7. 用四种排序方式对所有联系人进行排序

 二.项目功能演示

要编写一个通讯录项目,首先要明确我们想要达到的效果是什么样,下面我将用vs2022编译器来为大家演示一下通讯录运行时的样子:

首先,我们来到菜单界面,提醒用户选择通讯录中的某一功能:


 当用户选择'0'时,退出程序


 当用户选择'1'时,依次提醒用户输入增添的联系人信息,包括名字,年龄,性别,地址,电话.

输入完毕后提示用户联系人添加成功:


 当用户输入'2'时,提示用户输入要删除的人的名字,当用户输入后,提示删除成功:

 当没有找到要删除的对象时,提示用户没有找到要删除的对象:

 


用户输入'3'时, 提示用户输入要查找的联系人姓名,并在找到后打印出该联系人的信息:

如果没有找到,则提示用户没有找到该联系人:

 


用户输入'4'时,提示用户输入要修改的人的名字,并在之后提示用户依次输入修改后的该联系人信息,录入完成后,提示修改成功并再次打印修改后的该联系人信息.

 当用户输入联系人不存在时,提示用户没有找到要修改的对象:


 当用户选择'5'时,打印当前通讯录中所有联系人的信息:


用户选择'7'时, 提示用户选择排序方式.

选择1时,则将通讯录按姓名排序并打印排序结果:

 当选择2时,则将通讯录按年龄排序并打印排序结果:

 当选择3时,则将通讯录按性别排序并打印排序结果:

 当选择4时,则将通讯录按住址排序并打印排序结果:


用户选择'6'时,清空通讯录中的所有联系人信息:

当通讯录原本为空时,提示用户无需清空:


 以上就是通讯录的功能演示,下面我们则需要分12步,逐步实现上面演示的所有功能.


三.逐步实现项目功能及其逻辑详解

通过第二部分对项目功能的介绍,我们已经对通讯录的功能有了大致的了解,虽然看似需要实现的功能很多,貌似一时间不知该如何下手,但我们可以分步分模块来分析这个项目的流程,最后再将各各部分进行整合,所以大家不用担心,跟着我一步一步分析吧!


!!!注意,该部分的代码只是为了详细介绍某一部分的项目实现逻辑,故可能会删减一些与该部分不相关的代码以便大家理解,需要查看完整详细代码可以移步本文第四部分。


1.实现通讯录菜单

菜单部分的逻辑比较简单,就是利用C语言printf函数打印出这个菜单界面即可。基础问题就不过多赘述了,代码如下:

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

2.实现通讯录程序功能可循环使用

由于我们要实现通讯录功能可以反复使用的逻辑,因此选择do...while的循环语句来实现这一部分的逻辑,该部分每步的详细解释见代码注释:

void menu()//菜单函数实现打印菜单
{printf("******************************************\n");printf("******************************************\n");printf("*******      1.add      2.del      *******\n");printf("*******      3.search   4.modify   *******\n");printf("*******      5.show     6.empty    *******\n");printf("*******      7.sort     0.exit     *******\n");printf("******************************************\n");printf("******************************************\n");
}int main()
{int input = 0;Contact con;//创建通讯录InitContact(&con);//初始化通讯录do//使用do  while语句来实现通讯录功能可以反复使用{menu();//菜单函数,打印菜单提示用户选择printf("请选择:>");//提醒用户选择scanf("%d", &input);//用scanf接收用户选择存入变量input中switch (input)//利用分支语句实现用户的选择{case 1://当用户选择'1',增添联系人AddContact(&con);break;case 2://当用户选择'2',删除联系人DelContact(&con);break;case 3://当用户选择'3',查找联系人searchContact(&con);break;case 4://当用户选择'4',修改联系人modifyContact(&con);break;case 5://当用户选择'5',打印联系人ShowContact(&con);break;case 6://当用户选择'6',清空联系人EmptyContact(&con);break;case 7://当用户选择'7',排序联系人SortContact(&con);break;case 0://当用户输入0,提醒用户退出程序printf("退出程序:>\n");break;default://当用户输入了非选项数字时,提醒用户重新输入printf("输入非法,请重新输入!\n");break;}} while (input);//用变量input的值作为while循环的判定执行条件//当input不为0时,该循环都可一直运行下去。return 0;
}

3.创建通讯录

创建通讯录成员的结构体应包括:姓名,年龄,性别,地址和电话这5个信息.

因此我们创建PeoInfo结构体类型时应由四个字符数组以及一个整形来组成.

同时我们需要一个整形来记录目前该通讯录中已存入的联系人个数.

因此我们创建Contact结构体类型时应由一个整形sz及一个结构体数组data组成.

而使用宏定义可以方便我们后续对各个结构的大小做调整.

综上,该部分代码如下:

#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 6
#define ADDR_MAX 30
#define TELE_MAX 12//人的信息-结构体
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char addr[ADDR_MAX];char tele[TELE_MAX];//电话11位,留一位给'\0';
}PeoInfo;typedef struct Contact
{PeoInfo data[MAX];//存放1000个人的信息int sz;//用来记录当前已经存放的信息的个数
}Contact;

 4.初始化通讯录

初始化通讯录的逻辑非常简单,我们使用memset()函数完成对date结构体数组的空间初始化即可.

该部分代码如下:

//初始化通讯录成员
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}

 5.添加联系人信息

要添加联系人信息,首先需要判断当前通讯录是否还能添加,即判断联系人是否已经满了.

其次只需要逐一接收用户输入的信息存入对应结构体中即可:

该部分代码如下:

void AddContact(Contact* pc)
{assert(pc);//防止通讯录满了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].tele);//每次录入完,sz自增pc->sz++;printf("联系人添加成功:>\n");
}

 6.按任人名查找指定联系人

因为后续删除,查找,修改等功能都是以输入姓名然后查找到对应联系人后进行操作的,

所以我们提前编写好一个用于人名查询的被调函数,

该被调函数的功能为:接收主调函数传入的人名信息,并在通讯录中查找,

如果找到了返回该联系人在通讯录中的序号,如果没有找到返回-1.

代码如下:

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

7.删除指定联系人信息

要删除首先要判断当前通讯录联系人个数是否为0,为0则无法再进行删除操作.

其次提示用户输入要删除的联系人姓名,交给FindByName()函数查找,

如果找到了,则从该位置依次前移联系人,从而达到删除联系人的效果,图示如下:

 如果没有找到用户输入的联系人信息则不执行,代码如下:

void DelContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };//防止通讯录删完了if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//找到要删除的对象printf("请输入要删除的人的名字:>");scanf("%s", name);int del=FindByName(pc,name);if (-1== del){printf("抱歉,没有找到您要删除的对象;<\n");return;}int i = 0;//删除for (i = del; i < pc->sz-1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功;>\n");
}

8.查找联系人信息并打印

该部分实现较为简单,只需要借助FindByName函数找到联系人位置并打印其信息即可,

代码如下:

void searchContact(const Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };//找到要查找的对象printf("请输入要查找的人的名字:>");scanf("%s", name);int sea = FindByName(pc, name);if (-1 == sea){printf("抱歉,没有找到您要查找的对象;<\n");return;}//打印信息printf("________________________________________________________________________________________\n");printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");printf("________________________________________________________________________________________\n");printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n",sea+1,pc->data[sea].name,pc->data[sea].age,pc->data[sea].sex,pc->data[sea].addr,pc->data[sea].tele);printf("________________________________________________________________________________________\n");
}

 9.修改指定联系人信息

该部分功能实现较为简单,只需要借助FindByName函数找到联系人位置并在重新录入其信息后打印修改后的信息即可,

代码如下:

void modifyContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };//找到要修改的对象printf("请输入要修改的人的名字:>");scanf("%s", name);int mod = FindByName(pc, name);if (-1 == mod){printf("抱歉,没有找到您要修改的对象;<\n");return;}printf("请输入修改后的联系人信息\n");printf("请输入名字;>");scanf("%s", pc->data[mod].name);printf("请输入年龄;>");scanf("%d", &(pc->data[mod].age));printf("请输入性别;>");scanf("%s", pc->data[mod].sex);printf("请输入地址;>");scanf("%s", pc->data[mod].addr);printf("请输入电话;>");scanf("%s", pc->data[mod].tele);printf("修改成功;>\n");printf("________________________________________________________________________________________\n");printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");printf("________________________________________________________________________________________\n");printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n", mod + 1,pc->data[mod].name,pc->data[mod].age,pc->data[mod].sex,pc->data[mod].addr,pc->data[mod].tele);printf("________________________________________________________________________________________\n");
}

 10.显示所有联系人信息

该部分只需要借助循环结构将通讯录中所有成员打印即可,但需要使用大量格式控制符来确保打印的通讯录整洁,美观.

代码如下:

void ShowContact(const Contact* pc)
{ assert(pc);if (pc->sz == 0){printf("通讯录为空,无法显示\n");return;}int i = 0;printf("________________________________________________________________________________________\n");printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号","|姓名", "|年龄", "|性别", "|地址", "|电话");for (i = 0; i < pc->sz; i++){printf("________________________________________________________________________________________\n");printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n",i+1,pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].tele);}printf("________________________________________________________________________________________\n");}

 11.清空所有联系人

清空所有联系人的逻辑与最开始的初始化通讯录的逻辑相同,借助memset()函数完成即可,

但在清空前需要判断当前通讯录是否为空,如果为空则不需要进行清空操作,

代码如下:

void EmptyContact(Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无需清空\n");return;}pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));printf("清空成功:>\n");}

 12.用四种排序方式给所有联系人排序

该部分分为两个模块:

  1. 排序逻辑的实现
  2. 借助qsort函数排序,需要完成排序函数comper的编写.

在实现第一模块时,尤其要注意使用qsort()函数时参数的传递,如果有对qsort()函数还不了解的朋友可以移步我的这篇博客:qsort()函数详解:能给万物排序的神奇函数

里面有0基础的qsort()函数(快速排序函数)的详解,应该可以帮助你完全掌握该函数.

下面是第一模块的代码:

//给联系人排序
void SortContact(Contact* pc)
{int cho = 0;if (pc->sz == 0){printf("通讯录为空,请先加入联系人\n");return;}printf("******************************\n");printf("********   1.按姓名  *********\n");printf("********   2.按年龄  *********\n");printf("********   3.按性别  *********\n");printf("********   4.按地址  *********\n");printf("******************************\n");printf("请选择您想使用的排序方式:>");scanf("%d", &cho);int (*compare_func)(const void*, const void*) = NULL;switch (cho){case 1:compare_func = comper_name;break;case 2:compare_func = comper_age;break;case 3:compare_func = comper_sex;break;case 4:compare_func = comper_addr;break;default:printf("排序选项无效:<\n");return;}// 使用qsort函数进行排序qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_func);printf("排序成功:>\n");ShowContact(pc);
}

下面是第二模块的代码:

//comper按姓名排序
int comper_name(const void* a, const void* b)
{const PeoInfo* personA = (const PeoInfo*)a;const PeoInfo* personB = (const PeoInfo*)b;return strcmp(personA->name, personB->name);
}
//comper按年龄排序
int comper_age(const void* a, const void* b)
{const PeoInfo* personA = (const PeoInfo*)a;const PeoInfo* personB = (const PeoInfo*)b;return (personA->age-personB->age);
}
//comper按性别排序
int comper_sex(const void* a, const void* b) 
{const PeoInfo* personA = (const PeoInfo*)a;const PeoInfo* personB = (const PeoInfo*)b;return strcmp(personA->sex, personB->sex);
}
//comper按住处排序
int comper_addr(const void* a, const void* b) 
{const PeoInfo* personA = (const PeoInfo*)a;const PeoInfo* personB = (const PeoInfo*)b;return strcmp(personA->addr, personB->addr);
}

 四.整合代码并测试运行

我们将程序运行的代码分为三个模块分开书写,完整代码如下:

contact.c

//contact.c通讯录的实现
#include"contact.h"//初始化通讯录成员
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}//增加通讯录中的联系人
void AddContact(Contact* pc)
{assert(pc);//防止通讯录满了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].tele);//每次录入完,sz自增pc->sz++;printf("联系人添加成功:>\n");
}//按人名查找联系人
int FindByName(const Contact* pc, char* name)
{assert(pc);int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}//删除通讯录中的成员
void DelContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };//防止通讯录删完了if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//找到要删除的对象printf("请输入要删除的人的名字:>");scanf("%s", name);int del=FindByName(pc,name);if (-1== del){printf("抱歉,没有找到您要删除的对象;<\n");return;}int i = 0;//删除for (i = del; i < pc->sz-1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功;>\n");
}//查找联系人信息并打印
void searchContact(const Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };//找到要查找的对象printf("请输入要查找的人的名字:>");scanf("%s", name);int sea = FindByName(pc, name);if (-1 == sea){printf("抱歉,没有找到您要查找的对象;<\n");return;}//打印信息printf("________________________________________________________________________________________\n");printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");printf("________________________________________________________________________________________\n");printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n",sea+1,pc->data[sea].name,pc->data[sea].age,pc->data[sea].sex,pc->data[sea].addr,pc->data[sea].tele);printf("________________________________________________________________________________________\n");
}//修改联系人信息
void modifyContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };//找到要修改的对象printf("请输入要修改的人的名字:>");scanf("%s", name);int mod = FindByName(pc, name);if (-1 == mod){printf("抱歉,没有找到您要修改的对象;<\n");return;}printf("请输入修改后的联系人信息\n");printf("请输入名字;>");scanf("%s", pc->data[mod].name);printf("请输入年龄;>");scanf("%d", &(pc->data[mod].age));printf("请输入性别;>");scanf("%s", pc->data[mod].sex);printf("请输入地址;>");scanf("%s", pc->data[mod].addr);printf("请输入电话;>");scanf("%s", pc->data[mod].tele);printf("修改成功;>\n");printf("________________________________________________________________________________________\n");printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");printf("________________________________________________________________________________________\n");printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n", mod + 1,pc->data[mod].name,pc->data[mod].age,pc->data[mod].sex,pc->data[mod].addr,pc->data[mod].tele);printf("________________________________________________________________________________________\n");
}//显示通讯录中的信息
void ShowContact(const Contact* pc)
{ assert(pc);if (pc->sz == 0){printf("通讯录为空,无法显示\n");return;}int i = 0;printf("________________________________________________________________________________________\n");printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号","|姓名", "|年龄", "|性别", "|地址", "|电话");for (i = 0; i < pc->sz; i++){printf("________________________________________________________________________________________\n");printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n",i+1,pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].tele);}printf("________________________________________________________________________________________\n");}//清空联系人信息
void EmptyContact(Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无需清空\n");return;}pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));printf("清空成功:>\n");}//comper按姓名排序
int comper_name(const void* a, const void* b)
{const PeoInfo* personA = (const PeoInfo*)a;const PeoInfo* personB = (const PeoInfo*)b;return strcmp(personA->name, personB->name);
}
//comper按年龄排序
int comper_age(const void* a, const void* b)
{const PeoInfo* personA = (const PeoInfo*)a;const PeoInfo* personB = (const PeoInfo*)b;return (personA->age-personB->age);
}
//comper按性别排序
int comper_sex(const void* a, const void* b) 
{const PeoInfo* personA = (const PeoInfo*)a;const PeoInfo* personB = (const PeoInfo*)b;return strcmp(personA->sex, personB->sex);
}
//comper按住处排序
int comper_addr(const void* a, const void* b) 
{const PeoInfo* personA = (const PeoInfo*)a;const PeoInfo* personB = (const PeoInfo*)b;return strcmp(personA->addr, personB->addr);
}//给联系人排序
void SortContact(Contact* pc)
{int cho = 0;if (pc->sz == 0){printf("通讯录为空,请先加入联系人\n");return;}printf("******************************\n");printf("********   1.按姓名  *********\n");printf("********   2.按年龄  *********\n");printf("********   3.按性别  *********\n");printf("********   4.按地址  *********\n");printf("******************************\n");printf("请选择您想使用的排序方式:>");scanf("%d", &cho);int (*compare_func)(const void*, const void*) = NULL;switch (cho){case 1:compare_func = comper_name;break;case 2:compare_func = comper_age;break;case 3:compare_func = comper_sex;break;case 4:compare_func = comper_addr;break;default:printf("排序选项无效:<\n");return;}// 使用qsort函数进行排序qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_func);printf("排序成功:>\n");ShowContact(pc);
}

contact.h

#pragma once
//contact.h函数的声明
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 6
#define ADDR_MAX 30
#define TELE_MAX 12//人的信息-结构体
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char addr[ADDR_MAX];char tele[TELE_MAX];//电话11位,留一位给'\0';
}PeoInfo;typedef struct Contact
{PeoInfo data[MAX];//存放1000个人的信息int sz;//用来记录当前已经存放的信息的个数
}Contact;//初始化通讯录
void InitContact(Contact* pc);//增加联系人
void AddContact(Contact* pc);//删除通讯录中的信息
void DelContact(Contact* pc);//显示通讯录中的信息
void ShowContact(const Contact* pc);//查找联系人并打印其信息
void searchContact(const Contact* pc);//修改联系人信息
void modifyContact(Contact* pc);//清空联系人信息(和初始化逻辑一模一样)
void EmptyContact(Contact* pc);//给联系人排序
void SortContact(Contact* pc);

test.c

//bit.c测试通讯录#include"contact.h"void menu()
{printf("******************************************\n");printf("******************************************\n");printf("*******      1.add      2.del      *******\n");printf("*******      3.search   4.modify   *******\n");printf("*******      5.show     6.empty    *******\n");printf("*******      7.sort     0.exit     *******\n");printf("******************************************\n");printf("******************************************\n");
}int main()
{int input = 0;//创建通讯录Contact con;//初始化通讯录InitContact(&con);do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:searchContact(&con);break;case 4:modifyContact(&con);break;case 5:ShowContact(&con);break;case 6:EmptyContact(&con);break;case 7:SortContact(&con);break;case 0:printf("退出程序:>\n");break;default:printf("输入非法,请重新输入!\n");break;}} while (input);return 0;
}

测试运行部分则在开篇项目功能演示部分就已经测试运行过了,有兴趣的朋友可以将代码拷贝在自己的编译器中运行完善,篇幅有限,我就不多赘述了.

有什么问题,欢迎大家留言和我一起讨论.

感谢您的支持,这是我创作的最大动力.

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

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

相关文章

统计学和机器学习之间的联系和区别

一、说明 老实说&#xff0c;我厌倦了几乎每天都在社交媒体和我的大学里听到这场辩论。通常&#xff0c;这伴随着一些模糊的陈述来解释这个问题。双方都为此感到内疚。我希望在本文结束时&#xff0c;您将对这些有些模糊的术语有更明智的立场。 二、论点 与普遍的看法相反&…

ASPICE学习笔记

文章目录 1. ASPICE是什么?2. ASPICE能干什么?2.1 过程参考模型2.2 过程评估模型参考1. ASPICE是什么? ASPICE的全称是Automotive SPICE。很明显的看出ASPICE是由SPICE发展而来。而SPICE是由国际标准化组织ISO、国际电工委员会IEC、信息技术委员会JTC1发起制定的ISO15504标…

企业数字化转型与股利分配(2007-2021年)

参照李滟&#xff08;2023&#xff09;的做法&#xff0c;本团队对来自西南大学学报&#xff08;社会科学版&#xff09;《企业数字化转型与股利分配》一文中的基准回归部分进行复刻。 企业数字化转型已成为我国经济增长的新引擎和新动力。为探究数字化转型对企业财务决策的影…

LeetCode 1289. 下降路径最小和 II:通俗易懂地讲解O(n^2) + O(1)的做法

【LetMeFly】1289.下降路径最小和 II&#xff1a;通俗易懂地讲解O(n^2) O(1)的做法 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-falling-path-sum-ii/ 给你一个 n x n 整数矩阵 arr &#xff0c;请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下…

函数(1)

1. 函数是什么&#xff1f; 数学中我们常见到函数的概念。但是你了解C语言中的函数吗&#xff1f; 维基百科中对函数的定义&#xff1a;子程序 在计算机科学中&#xff0c;子程序&#xff08;英语&#xff1a;Subroutine, procedure, function, routine, method, subprogram, …

“先锋龙颜美学”,比亚迪宋L 完成工信部申报,单双电机正式上市

根据工信部最新发布的《道路机动车辆生产企业及产品公告》&#xff08;第 374 批&#xff09;&#xff0c;我们得知比亚迪汽车公司的新款车型宋 L 已经顺利完成申报&#xff0c;并成功获得核准。这款车型将会有两个版本&#xff0c;分别是单电机和双电机版本。 此外&#xff0c…

Android T 窗口层级其二 —— 层级结构树的构建(更新中)

如何通过dump中的内容找到对应的代码&#xff1f; 我们dump窗口层级发现会有很多信息&#xff0c;adb shell dumpsys activity containers 这里我们以其中的DefaultTaskDisplayArea为例 在源码的framework目录下查找该字符串&#xff0c;找到对应的代码就可以通过打印堆栈或者…

VSCODE[配置ssh免密远程登录]

配置ssh免密远程登录 本文摘录于&#xff1a;https://blog.csdn.net/qq_44571245/article/details/123031276只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 这里要注意如下几个地方: 1.要进入.ssh目录创建文件: 2.是拷贝带"ssh-…

【LeetCode】55. 跳跃游戏 - 贪婪算法

目录标题 2023-8-10 16:27:05 55. 跳跃游戏 2023-8-10 16:27:05 class Solution {public boolean canJump(int[] nums) {int n nums.length;int arrivalLocation 0;for (int i 0; i < n; i) {if (i < arrivalLocation) {arrivalLocation Math.max(arrivalLocation,…

手把手教你如何零成本搭建网站实现内网穿透从而创建自己的数据隧道

手把手教你如何零成本搭建网站实现内网穿透从而创建自己的数据隧道 文章目录 手把手教你如何零成本搭建网站实现内网穿透从而创建自己的数据隧道前言1. 安装网站运行和发布必备软件2. 安装PHPStudy3. 安装wordpress4. 进入wordpress安装程序&#xff0c;进行网页编辑和设置5. 安…

Windows Oracle21C与PLSQL Developer 15配置

1、下载Oracle21c并安装 下载地址&#xff1a;https://www.oracle.com/database/technologies/oracle21c-windows-downloads.html 2、下载PLSQL Developer 15并安装 下载地址&#xff1a;https://www.allroundautomations.com/products/pl-sql-developer/#pricing 3、配置O…

Claude 2、ChatGPT、Google Bard优劣势比较

​Claude 2&#xff1a; 优势&#xff1a;Claude 2能够一次性处理多达10万个tokens&#xff08;约7.5万个单词&#xff09;。 tokens数量反映了模型可以处理的文本长度和上下文数量。tokens越多&#xff0c;模型理解语义的能力就越强&#xff09;。它在法律、数学和编码等多个…

K8S MetalLB LoadBalancer

1. 简介 kubernetes集群没有L4负载均衡&#xff0c;对外暴漏服务时&#xff0c;只能使用nodePort的方式&#xff0c;比较麻烦&#xff0c;必须要记住不同的端口号。 LoadBalancer&#xff1a;使用云提供商的负载均衡器向外部暴露服务&#xff0c;外部负载均衡器可以将流量路由…

Leaflet入门,Leaflet如何自定义版权信息,以vue2-leaflet修改自定义版权为例

前言 本章讲解使用Leaflet的vue2-leaflet或者vue-leaflet插件来实现自定义版权信息的功能。 # 实现效果演示 见图片右下角版权信息 vue如何使用Leaflet vue2如何使用:《Leaflet入门,如何使用vue2-leaflet实现vue2双向绑定式的使用Leaflet地图,以及初始化后拿到leaflet对象…

Java获取指定文件夹下目录下所有视频并复制到另一个地方

import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption;public class VideoCopier {public static void main(String[] args) {// 指定源文件夹路径和目标文件夹路径String sourceFolderPath "path/to…

OSI参考模型及TCP/IP协议栈

一、网络概述 1.1、什么是网络&#xff1f; 1、网络的本质就是实现资源共享 2、将各个系统联系到一起&#xff0c;形成信息传递、接收、共享的信息交互平台 1.2、典型的园区网拓扑 1.3、网络历史发展&#xff0c;ARPA和ARPANET 1、1969年&#xff0c;美国国防部高级研究计…

8.10论文阅读

文章目录 The multimodal MRI brain tumor segmentation based on AD-Net摘要本文方法损失函数 实验结果 max-vit - unet:多轴注意力医学图像分割摘要本文方法实验结果 The multimodal MRI brain tumor segmentation based on AD-Net 摘要 基于磁共振成像(MRI)的多模态胶质瘤…

JavaEE——网络编程(UDP套接字编程)

文章目录 一、简单理解Socket 套接字二、UDP 数据报套接字编程三、编写简单的 UDP 版本服务器客户端1. 编写 UDP 版本的回显服务器回显服务器整体代码罗列 2. 编写 UDP 版本的回显客户端回显客户端整体代码罗列 四、总结与代码运行结果解释 一、简单理解Socket 套接字 概念&am…

100天精通Golang(基础入门篇)——第18天:深入解析Go语言中的结构体

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to Golang Language.✨✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1…

半导体芯片介质膜层膜层膜厚测量仪

镀膜是半导体芯片制备过程中的重要步骤。在一个完整的CMOS工艺流程中&#xff0c;介质膜层(保护层、外延层、光刻胶和栅极氧化物等)与金属沉积层交替出现。随着芯片工艺节点不断进步&#xff0c;介质膜层也变得越来越复杂&#xff0c;在7nm工艺中&#xff0c;所需测量的介质膜堆…