【C语言期末项目-通讯录】-升级可动态申请内存版(手把手详细过程,期末评分A+的项目,答辩辅助神博文,建议三连点赞收藏)

目录

​编辑

前言:

 1.项目功能需求分析 

2.文件框架说明 

3.程序主框架实现 

4.创建联系人结构体类型和通讯录结构体类型 

4.1创建通讯录 

5.程序功能实现--封装功能函数实现不同功能 

5.1通讯录初始化

 5.2增加联系人 

 5.3显示所有联系人的信息

5.4删除指定联系人的信息 

5.5查找指定联系人 

 5.6修改联系人的信息

 6.释放通讯录

7.测试通讯录动态增长 

6.结语及源码


前言:

对于这个项目,是前面数组基础版本的通讯录的升级版本,大家如果一步理解有困难,一定先点击我的主页了解一下前几篇博客的内容做一个铺垫,我这里罗列一下关联最大的三篇:

①动态内存详解

②通讯录基础数组版本

③C语言结构体详解

 1.项目功能需求分析 

实现一个通讯录:
通讯录保存个人信息

 名字,年龄 性别 电话 住址    用保存人的信息的结构体实现

1.通讯录空间不固定,可以先存放一部分的信息,当用户还要存入信息的时候可以自动增加容量。

(比如默认先存放3个联系人的信息,不够了,就每次增加两个联系人信息的空间给用户)
 2.添加联系人
3.删除指定联系人
4.查找指定联系人
5.显示所有人的信息
6.排序功能

7.可以修改指定联系人的信息

2.文件框架说明 

test.c 主菜单文件,用于功能测试

contact.c 函数具体实现文件

contact.h 存放函数和类型的声明和必要头文件

3.程序主框架实现 

我们希望在程序中实现不同的操作,比如上述的增删查改联系人的信息,而不是执行一次程序就结束,用户可以选择退出。接下来我们就实现一下主体框架,包含主页面菜单显示。

void menu()
{printf("----------------------------------\n");printf("|***0.Exit       1.ADD***********|\n");printf("|***2.DEL       3.SEARCH*********|\n");printf("|***4.MODIFY    5.SHOW***********|\n");printf("|***6.SORT       ****************|\n");printf("----------------------------------\n");}
void test()
{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("退出程序成功\n");break;default:printf("选择错误,请根据菜单选项进行功能选择,谢谢配合\n");break;}} while (input);
}int main()
{test();return 0;
}

case后面的选项是1,2,3,4,5,那么我们想可不可以利用枚举,让case后面的选项既能表示我们的功能含义又能表示功能选择数字,这样的代码可读性就会更高一些,我们就可以修改如下 :

首先定义选择枚举类型:

enum OPtion
{EXIT,//0ADD,//1DEL,//2SEARCH,MODIFY,SHOW,SORT};

这个依然是放在我们的头文件中去定义,这样代码的整体美观些,接下来的结构修改为:

void menu()
{printf("----------------------------------\n");printf("|***0.Exit       1.ADD***********|\n");printf("|***2.DEL       3.SEARCH*********|\n");printf("|***4.MODIFY    5.SHOW***********|\n");printf("|***6.SORT       ****************|\n");printf("----------------------------------\n");}
void test()
{int  input = 0;Contact con;InitContact(&con);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("退出程序成功\n");break;default:printf("选择错误,请根据菜单选项进行功能选择,谢谢配合\n");break;}} while (input);
}int main()
{test();return 0;
}

4.创建联系人结构体类型和通讯录结构体类型 

由于通讯录存储的是每一个联系人的基本信息,名字、电话、性别、住址等,所以我们可以封装一个联系人结构体类型用于描述每一个联系人。

typedef struct PeoInfo
{char name[20];int age;char sex[5];char telepnumber[12];char addr[30];} PeoInfo;

为了后续书写的方便将struct PeoInfo类型重定义为PeoInfo

我们现在需要一块空间来存储我们联系人的信息,这块空间的起始地址交给我们的一个联系人结构体类型的指针。

PeoInfo* data;//指向了存放数据的空间

由于,我们后续会对通讯录进行增删操作,就会改变数组的大小,为了方便查看或者显示或者为了方便操作我们可以定义一个SZ来记录数组的大小,增加一个联系人,sz+1.......

int sz;//记录的是当前有效元素的个数

这,当我们起始有三个联系人类型那么大的空间的时候,还没有存入联系人的信息,此时我们的sz=0,那么我们什么时候开始扩大我们的空间呢,所以我们专门设计一个变量来记录我们通讯录的数据空间容量,起始容量为3,当sz 等于我们的容量的时候,就可以扩容了。

int  capacity;//记录当前存放数据空间的容量

数据区,容量和联系人数目都是通讯录的属性,我们可以设计一下通讯录类型结构体:

typedef struct Contact
{PeoInfo* data;//指向了存放数据的空间int sz;//记录的是当前有效元素的个数int  capacity;//记录当前存放数据空间的容量}Contact;

为了以后书写方便,用typedef重定义通讯录结构体类型为:Contact类型。

4.1创建通讯录 

当我们的通讯录类型有了过后,我们就可以创建一个通讯录:

5.程序功能实现--封装功能函数实现不同功能 

5.1通讯录初始化

初始化函数,首先要为我们的data数据区申请3个PeoINfo类型的空间,将sz也初始化为0.将容量初始化3,起始的容量不一定设置为3,方便不同的伙伴来设置,我们将容量的大小也设置为宏.我们传参使用了结构体地址传参,接收参数使用了结构体指针,内存占用少。

void Initcontact(Contact* pc)
{assert(pc);pc->data = (PeoInfo*)malloc(CAPICITY * sizeof(PeoInfo));if (pc->data == NULL){perror("Initcontact");}pc->sz = 0;pc->capacity = CAPICITY;
}

 5.2增加联系人 

在动态版本中,我们不用考虑通讯录满没满。而是应该考虑通讯录申请的空间是否够了,不够就要扩容,每录入一个联系的信息,sz就+1,当我们的sz与我们的容量相等的时候,就要考虑扩容,所以我们进入增加函数第一步就应该先判断是否要增容。

为了代码方便,我们将检查是否要增容这一步封装为一个函数:

int ChekCapacity(Contact* pc)
{if (pc->sz == pc->capacity){PeoInfo* ptr =(PeoInfo * )realloc(pc->data, (pc->capacity + 2 * sizeof(PeoInfo)));if (ptr == NULL){perror("ChekCapaticy");return  0;}else{pc->data = ptr;pc->capacity += 2;}}return 1;
}

函数返回1,说明增容成功,函数返回0说明增容失败。当然,也不一定每次只增加两个空间,我们还是将增加的空间数目定义为宏,方便伙伴们修改:

#define ADDC 2
void Initcontact(Contact* pc)
{assert(pc);pc->data = (PeoInfo*)malloc(CAPICITY * sizeof(PeoInfo));if (pc->data == NULL){perror("Initcontact");}pc->sz = 0;pc->capacity = CAPICITY;
}
int ChekCapacity(Contact* pc)
{if (pc->sz == pc->capacity){PeoInfo* ptr =(PeoInfo * )realloc(pc->data, (pc->capacity + ADDC * sizeof(PeoInfo)));if (ptr == NULL){perror("ChekCapaticy");return  0;}else{pc->data = ptr;pc->capacity += ADDC;printf("增容成功\n");
return1;}}return 1;
}

我们的增加联系人的函数为:

void AddContact(Contact* pc)
{assert(pc);//断言防止传入空指针//首先判断通讯录满每满if (0 == ChekCapacity(pc)){return;}printf("请输入联系人的名字>\n");scanf("%s", pc->data[pc->sz].name);//由于name是数组名这里就不要&符号了printf("请输入联系人的年龄>\n");scanf("%d", &(pc->data[pc->sz].age));printf("请输入联系人的性别>\n");scanf("%s", pc->data[pc->sz].sex);printf("请输入联系人的电话>\n");scanf("%s", pc->data[pc->sz].telepnumber);printf("请输入联系人的地址>\n");scanf("%s", pc->data[pc->sz].addr); //添加联系人成功,我们sz++pc->sz++;printf("添加联系人成功\n");}

 

 5.3显示所有联系人的信息

为了看一下我们添加联系人或者删除联系人的效果,我们这里就先写显示函数

用于我们只是显示通讯录信息,并不将参数内容进行修改所以参数最好使用const进行修饰,防止出错,这一步不理解的伙伴可以点击我的主页看一下我讲解const的博文。

这个函数我们只用循环打印我们data数组内容就行

void ShowContact(const Contact* pc)
{assert(pc);//断言一下防止传入空指针int i = 0;printf("————————————————————————————————————————————————————————————————————————————————————————\n");printf("|%-20s\t|%-4s\t|%-5s\t|%-12s\t|%-30s|\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("|%-20s\t|%-4d\t|%-5s\t|%-12s\t|%-30s|\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].telepnumber,pc->data[i].addr);printf("————————————————————————————————————————————————————————————————————————————————————————\n");}printf("————————————————————————————————————————————————————————————————————————————————————————\n");

我们来看一下前两个函数执行的效果:

5.4删除指定联系人的信息 

首先,如果通讯录为空,我们就没有删除的东西

第二,要删除对应联系人的信息,实现思想是先找到对应联系人的名字匹配相同将后面的内容前移覆盖完成删除。

void DelCotact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}char name[DATAMAX] = { 0 };assert(pc);//断言,防止传入空指针printf("请输入要删除的人的名字:》\n");scanf("%s", name);//遍历找到要删除的人int i = 0;int del = 0;int flag = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){del = i;flag = 1;break;}}if (flag == 0){printf("找不到要删除的人,请检查名字是否输入正确\n");return;}//找到了,删除联系人for (i = del; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("成功删除联系人\n");
}

由于我们后面修改呀等等都会用到查找这个函数,所以我们将其封装为一个查找函数,那我们就可以改造代码如下:

int Findbyname(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 DelCotact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}char name[DATAMAX] = { 0 };assert(pc);//断言,防止传入空指针printf("请输入要删除的人的名字:》\n");scanf("%s", name);//遍历找到要删除的人int i = 0;int del = 0;del = Findbyname(pc, name);if (del == -1){printf("找不到要删除的人,请检查名字是否输入正确\n");return;}//找到了,删除联系人for (i = del; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("成功删除联系人\n");
}

我们来看一下效果:

5.5查找指定联系人 

这里我们就实现一下通过名字查找,之所以单独写一个查找函数是因为在功能中,查找到过后还要显示出来。

看实现:

void SearchContact(Contact* pc)
{assert(pc);char name[DATAMAX] = { 0 };printf("请输入要查找的人的名字:》\n");scanf("%s", name);int pos = Findbyname(pc, name);if (pos == -1){printf("要查找的人不存在,请检查名字是否输入正确\n");}else{printf("————————————————————————————————————————————————————————————————————————————————————————\n");printf("|%-20s\t|%-4s\t|%-5s\t|%-12s\t|%-30s|\n", "名字", "年龄", "性别", "电话", "地址");printf("————————————————————————————————————————————————————————————————————————————————————————\n");printf("|%-20s\t|%-4d\t|%-5s\t|%-12s\t|%-30s|\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].telepnumber,pc->data[pos].addr);printf("————————————————————————————————————————————————————————————————————————————————————————\n");}
}

这里查找也可以根据其他的比如号码等,可以利用Switch来实现。看一下效果:

 5.6修改联系人的信息

通过名字来找到要修改信息的联系人,然后重新录入信息

void 	ModifyContact(Contact* pc)
{assert(pc);char name[DATAMAX] = { 0 };printf("请输入要修改人的名字:>\n");scanf("%s", name);int pos = Findbyname(pc, name);if (pos == -1){printf("要修改的人不存在,请检查名字是否输入正确\n");}else{printf("请输入要修改人的名字>\n");scanf("%s", pc->data[pos].name);//由于name是数组名这里就不要&符号了printf("请输入要修改人的年龄>\n");scanf("%d", &(pc->data[pos].age));printf("请输入要修改人的性别>\n");scanf("%s", pc->data[pos].sex);printf("请输入要修改人的电话>\n");scanf("%s", pc->data[pos].telepnumber);printf("请输入要修改人的地址>\n");scanf("%s", pc->data[pos].addr); \printf("修改成功\n");}
}

我们看一下效果:

 6.释放通讯录

由于我们的通讯录空间是malloc来的,所以在最后程序结束应该将空间释放,防止造成内存泄漏。

那我们就在退出选项后面增加一个销毁函数:

void DestoryContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->capacity = 0;pc->sz = 0;
}

7.测试通讯录动态增长 

先往通讯录里面放入三个联系人信息:

下一步增容:

增容成功,我们展现一下通讯录然后我们查找一下2号联系人:

功能正常。到这里我们的动态版本就修改完成了。

6.结语及源码

以上就是本期的所有内容,大家可以配合解释和原码运行理解。创作不易,大家如果觉得还可以的话,欢迎大家三连,有问题的地方欢迎大家指正,一起交流学习,一起成长,我是Nicn,正在c++方向前行的奋斗者,感谢大家的关注与喜欢。下面附上整个项目源码。后续会陆续更新升级版,大家敬请期待。

test.c

#include"contact.h"//通讯录空间不固定,大小1可以调整
// 默认放3个人的信息,不够,每次增加两个void menu()
{printf("----------------------------------\n");printf("|***0.Exit       1.ADD***********|\n");printf("|***2.DEL       3.SEARCH*********|\n");printf("|***4.MODIFY    5.SHOW***********|\n");printf("|***6.SORT       ****************|\n");printf("----------------------------------\n");}
void test()
{int  input = 0;Contact con;Initcontact(&con);do{menu();printf("请选择:》");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelCotact(&con);break;case SEARCH:SearchContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case SORT:break;case EXIT:DestoryContact(&con);printf("退出程序成功\n");break;default:printf("选择错误,请根据菜单选项进行功能选择,谢谢配合\n");break;}} while (input);
}int main()
{test();return 0;
}

contact.h

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>#define DATAMAX 100
#define CAPICITY 3
#define ADDC 2enum OPtion
{EXIT,//0ADD,//1DEL,//2SEARCH,MODIFY,SHOW,SORT};//类型的声明
typedef struct PeoInfo
{char name[20];int age;char sex[5];char telepnumber[12];char addr[30];} PeoInfo;//typedef struct Contact
//{
//	PeoInfo data[DATAMAX];
//	int sz;
//}Contact;
typedef struct Contact
{PeoInfo* data;//指向了存放数据的空间int sz;//记录的是当前有效元素的个数int  capacity;//记录当前存放数据空间的容量}Contact;//初始化函数
void Initcontact(Contact* pc);//函数声明
void AddContact(Contact* pc);//增加联系人函数
void ShowContact(const Contact* pc);//显示通讯录信息
void DelCotact(Contact* pc);//删除联系人信息
void SearchContact(Contact* pc);//查找联系人的信息
void 	ModifyContact(Contact* pc);//修改联系人的信息
void DestoryContact(Contact* pc);//销毁通讯录

contact.c

#include"contact.h"
int Findbyname(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 Initcontact(Contact* pc)
{assert(pc);pc->data = (PeoInfo*)malloc(CAPICITY * sizeof(PeoInfo));if (pc->data == NULL){perror("Initcontact");}pc->sz = 0;pc->capacity = CAPICITY;
}
int ChekCapacity(Contact* pc)
{if (pc->sz == pc->capacity){PeoInfo* ptr =(PeoInfo * )realloc(pc->data, (pc->capacity + ADDC * sizeof(PeoInfo)));if (ptr == NULL){perror("ChekCapaticy");return  0;}else{pc->data = ptr;pc->capacity += ADDC;printf("增容成功\n");return 1;}}return 1;
}void AddContact(Contact* pc)
{assert(pc);//断言防止传入空指针//首先判断通讯录满每满if (0 == ChekCapacity(pc)){return;}printf("请输入联系人的名字>\n");scanf("%s", pc->data[pc->sz].name);//由于name是数组名这里就不要&符号了printf("请输入联系人的年龄>\n");scanf("%d", &(pc->data[pc->sz].age));printf("请输入联系人的性别>\n");scanf("%s", pc->data[pc->sz].sex);printf("请输入联系人的电话>\n");scanf("%s", pc->data[pc->sz].telepnumber);printf("请输入联系人的地址>\n");scanf("%s", pc->data[pc->sz].addr); //添加联系人成功,我们sz++pc->sz++;printf("添加联系人成功\n");}
void ShowContact(const Contact* pc)
{assert(pc);//断言一下防止传入空指针int i = 0;printf("————————————————————————————————————————————————————————————————————————————————————————\n");printf("|%-20s\t|%-4s\t|%-5s\t|%-12s\t|%-30s|\n", "名字", "年龄", "性别", "电话", "地址");printf("————————————————————————————————————————————————————————————————————————————————————————\n");for (i = 0; i < pc->sz; i++){printf("|%-20s\t|%-4d\t|%-5s\t|%-12s\t|%-30s|\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].telepnumber,pc->data[i].addr);printf("————————————————————————————————————————————————————————————————————————————————————————\n");}printf("————————————————————————————————————————————————————————————————————————————————————————\n");}void DelCotact(Contact* pc)
{if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}char name[DATAMAX] = { 0 };assert(pc);//断言,防止传入空指针printf("请输入要删除的人的名字:》\n");scanf("%s", name);//遍历找到要删除的人int i = 0;int del = 0;del = Findbyname(pc, name);if (del == -1){printf("找不到要删除的人,请检查名字是否输入正确\n");return;}//找到了,删除联系人for (i = del; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("成功删除联系人\n");
}void SearchContact(Contact* pc)
{assert(pc);char name[DATAMAX] = { 0 };printf("请输入要查找的人的名字:》\n");scanf("%s", name);int pos = Findbyname(pc, name);if (pos == -1){printf("要查找的人不存在,请检查名字是否输入正确\n");}else{printf("————————————————————————————————————————————————————————————————————————————————————————\n");printf("|%-20s\t|%-4s\t|%-5s\t|%-12s\t|%-30s|\n", "名字", "年龄", "性别", "电话", "地址");printf("————————————————————————————————————————————————————————————————————————————————————————\n");printf("|%-20s\t|%-4d\t|%-5s\t|%-12s\t|%-30s|\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].telepnumber,pc->data[pos].addr);printf("————————————————————————————————————————————————————————————————————————————————————————\n");}
}void 	ModifyContact(Contact* pc)
{assert(pc);char name[DATAMAX] = { 0 };printf("请输入要修改人的名字:>\n");scanf("%s", name);int pos = Findbyname(pc, name);if (pos == -1){printf("要修改的人不存在,请检查名字是否输入正确\n");}else{printf("请输入要修改人的名字>\n");scanf("%s", pc->data[pos].name);//由于name是数组名这里就不要&符号了printf("请输入要修改人的年龄>\n");scanf("%d", &(pc->data[pos].age));printf("请输入要修改人的性别>\n");scanf("%s", pc->data[pos].sex);printf("请输入要修改人的电话>\n");scanf("%s", pc->data[pos].telepnumber);printf("请输入要修改人的地址>\n");scanf("%s", pc->data[pos].addr); \printf("修改成功\n");}
}void DestoryContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->capacity = 0;pc->sz = 0;
}

 

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

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

相关文章

又见彩票事件(含米哈游算法变形题)

又见彩票事件 1月17日&#xff0c;中国体彩最新开奖结果出炉&#xff0c;其中“排列3”和“排列5”均出现罕见的“连5”组合。 体彩“排列3”的开奖号码为“555”&#xff0c;“排列5”的开奖号码为“55555”。 5亿奖池被清空。 开奖后第二天就有同学问我怎么看。 我 ... 我能怎…

python系统学习Day1

section1 python introduction 文中tips只做拓展&#xff0c;可跳过。 PartOne introduction 首先要对于python这门语言有一个宏观的认识&#xff0c;包括特点和应用场景。 特点分析&#xff1a; 优势 提供了完善的基础代码库&#xff0c;许多功能不必从零编写简单优雅 劣势 运…

Microsoft Word 超链接

Microsoft Word 超链接 1. 取消超链接2. 自动超链接2.1. 选项2.2. 校对 -> 自动更正选项2.3. Internet 及网络路径替换为超链接 References 1. 取消超链接 Ctrl A -> Ctrl Shift F9 2. 自动超链接 2.1. 选项 2.2. 校对 -> 自动更正选项 ​​​ 2.3. Internet…

JS逆向进阶篇【去哪儿旅行登录】【上篇】

目标url: aHR0cHM6Ly91c2VyLnF1bmFyLmNvbS9wYXNzcG9ydC9sb2dpbi5qc3A 实现难点&#xff1a; 逆向滑块请求发送短信登录 目录 每篇前言&#xff1a;0、前置技术栈&#xff08;1&#xff09;JS实现页面滑动&#xff08;2&#xff09;JS实现记录滑动轨迹&#xff08;3&#xff…

Pandas从基础统计到高级分析的完整指南【第77篇—Pandas高级分析】

Pandas从基础统计到高级分析的完整指南 在数据科学和分析领域中&#xff0c;Pandas是Python中最受欢迎的数据处理库之一。它提供了丰富而强大的功能&#xff0c;其中包括各种统计方法&#xff0c;用于更好地理解和分析数据。本文将介绍Pandas中常用的统计方法&#xff0c;通过…

分享80个jQuery特效,总有一款适合您

分享80个jQuery特效&#xff0c;总有一款适合您 80个jQuery特效下载链接&#xff1a;https://pan.baidu.com/s/1o8TcFu68r67e7VeiwmR-XQ?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理…

游泳耳机怎么选?四大口碑最好游泳耳机推荐

在挑选适合游泳的耳机时&#xff0c;选择合适的产品至关重要。游泳不仅是一项身体锻炼&#xff0c;更是一种享受。佩戴耳机能够为游泳者提供更加愉悦的体验&#xff0c;但确保所选耳机符合水中使用的要求至关重要。 传统的有线耳机和非防水设计的蓝牙耳机并不适合水中使用&…

牛客错题整理——C语言(实时更新)

1.以下程序的运行结果是&#xff08;&#xff09; #include <stdio.h> int main() { int sum, pad,pAd; sum pad 5; pAd sum, pAd, pad; printf("%d\n",pAd); }答案为7 由于赋值运算符的优先级高于逗号表达式&#xff0c;因此pAd sum, pAd, pad;等价于(…

嵌入式Qt Qt Creator安装与工程介绍

一.Qt概述 什么是Qt&#xff1a;Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立图形界面所需的所有功能。它是完全面向对象的&#xff0c;很容易扩展&#xff0c;并且允许真正的组件编程。 二.Qt Creator下载安装 下载地址&#xff1a;Index of /a…

从零开始实现消息队列(一)

从零开始实现消息队列 .什么是消息队列需求分析核心概念模型 . 什么是消息队列 相信大家都了解过阻塞队列和生产者消费者模型,而阻塞队列最大的用途,就是用于实现生产者消费者模型,生产者消费者模型有以下好处: 解耦合 解释: 当主机A给主机B发消息时,A给B发送请求,B给A返回响应…

C语言第二十三弹---指针(七)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1、sizeof和strlen的对比 1.1、sizeof 1.2、strlen 1.3、sizeof 和 strlen的对比 2、数组和指针笔试题解析 2.1、⼀维数组 2.2、二维数组 总结 1、si…

全坚固平板EM-I12U,全新升级后的优质体验

平板终端机在户外勘探、制造业、畜牧业、银行金融行业当中都不是陌生的&#xff0c;能采集各种数据来转换成信息流向企业和行业的各个分支当中&#xff0c;在整个行业发展、社会推动上面都起着关键性作用&#xff0c;而平板终端机的升级也就意味着未来的这些行业发展会进入一个…