通讯录----顺序表版本

本文详细描述了如何通过顺序表的逻辑实现通讯录功能,涉及结构体定义、初始化、销毁、添加、删除、修改、查找等操作,并展示了相关代码片段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.通讯录的实现逻辑

对于通讯录,我们做的无非就是初始化,销毁。添加联系人数据,修改联系人数据,删除联系人数据,查找联系人数据,展示联系人数据;

这个不就和我们的顺序表的逻辑如出一辙吗,顺序表实现的功能不就是数据的初始化,修改,删除(头删和尾删),添加(头插和尾插),顺序表的打印,这些我们是可以直接进行使用的;

我们的顺序表是整形的数据的删除,插入等等,那么我们的通讯录不是对整形数据进行相关的操作了,而是对联系人的信息进行相应的操作,我们把联系人及其相关的信息放到一个结构体里面,我们联系人的信息包括姓名性别年龄,电话以及地址这5项信息;

2.通讯录实现

(1)一些前期的准备

我们要在顺序表的基础上进行相应的操作,所以我们的解决方案在原来的seqlist.c---seqlist.h----test.c这三个基础上加上contact.c---contact.h这两个表示的是通讯录的源文件和头文件;

我们在通讯录的同文件里面定义结构体以及相关的函数的声明:

这里我们使用宏定义结构体里面数组(名字性别电话),方便我们对数组的大小进行相应的修改;

我们同时要把顺序表的头文件里面的int修改为我们联系人对应的结构体类型的数据,这个时候要包含通讯录对应的头文件;

通讯录的头文件要使用应该是对于顺序表进行初始化(实际上是对通讯录进行初始化),我们对顺序表进行初始化contactinit(sl* sl1),这个里面的sl就是我们的顺序表重定义之后的名字,sl1是形参,但是我们明明是要对通讯录进行初始化,参数确是顺序表这让人很难理解,我们于是写作contactinit(contact* con)这样就会很直观,但是两个头文件之间不能重复的包含,我们进行前置声明重定义:

因为我们的顺序表头文件里面的数据类型不是int ,我们的测试文件插入数据应该注释掉;顺序表的源文件里面打印整形数据,查找整形数据应该也注释掉,否则会报错

(2)通讯录的初始化和销毁

(3)添加联系人数据

我们定义一个结构体类型的变量:info把添加的信息写入到对应的成员里面去;

最后我们调用尾插函数插入到通讯录里面(也可以是头插函数);

(4)删除联系人数据

我们首先要判断删除的联系人是否存在,存在才能删除,不存在无法进行相应的操作;

我们后续进修改联系人数据的时候,也要进行判断我们想要修改的联系人是否存在,我们可以根据姓名进行判断是否存在,这个时候我们行定义一个函数fingbyname,因为是输入的联系人姓名和我们的通讯录里面的联系人姓名这两个字符串进行比较看是否相同,我们需要遍历整个通讯录,使用strcmp函数将我们输入的姓名和通讯录里面的姓名,进行比较,存在就返回0,不存在函数就返回-1;

我们最后是调用顺序表里面的slerase函数实现在指定的位置进行删除的操作,我们要传入通讯录和指定位置的下标;

(5)修改联系人数据

和删除的逻辑一样,先进行判断修改的联系人是否存在,调用findbyname函数根据返回值进行判断,最后输入新的联系人的相关的信息;

(6)查找联系人数据

和删除的逻辑一样,先进行判断查找的联系人是否存在,调用findbyname函数根据返回值进行判断,最后输出新的联系人的相关的信息;我们不使用展示是因为展示的是全部的,查找的时候只会展示我们想要查找的联系人的相关的信息,这个和展示的代码基本相同,只需要把数组对应的下标修改为我们的findbyname函数的返回值了;

(7)展示联系人数据

先打印表头栏目,在把我们的联系人的信息对应表头打印出来;

(8)项目的完善

作为一个项目,我们不能停留在测试功能上面,我们打印菜单栏,让用户可以自己选择相应的的功能进行实现,我们把所有的可以实现的功能放在菜单栏里面供用户进行选择:

我们的函数都已经实现了,所以设置switch循环的时候,直接调用就可以了;

3.完整代码

(1)seqlist.h

#pragma once
#include"contact.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef perinfo sldatatype;

typedef struct seqlist
{
	sldatatype* arr;
	int size;
	int capacity;
}sl;

//顺序表的初始化
void slinit(sl* ps);

//顺序表的销毁
void sldestory(sl* ps);

//顺序表的尾部插入数据
void slpushback(sl* ps, sldatatype x);

//顺序表的数组元素的打印
void slprint(sl s);

//顺序表的头部插入数据
void slpushfront(sl* ps, sldatatype x);

//顺序表的尾删
void slpopback(sl* ps);

//顺序表的头删
void slpopfront(sl* ps);

//顺序表的打印
void slprint(sl s);

//顺序表的指定插入
void slinsert(sl* ps, int pos, sldatatype x);

//顺序表的指定删除
void slerase(sl* ps, int pos);

//顺序表的数据的查找
int slfind(sl* ps, sldatatype x);

(2)seqlist.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"seqlist.h"
void check(sl* ps)
{
	if (ps->size == ps->capacity)
	{
		//我们插入数据,需要增大空间,动态内存开辟空间
		int newcapacity = ps->arr == 0 ? 4 : 2 * ps->capacity;
		sldatatype* temp = realloc(ps->arr, newcapacity * 2 * sizeof(sldatatype));
		if (temp == NULL)
		{
			perror("realloc");
			exit(1);//直接退出,不再继续执行
		}
		ps->arr = temp;
		ps->capacity = newcapacity;
	}
}
//顺序表的初始化
void slinit(sl* ps)
{
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
//顺序表的销毁
void sldestory(sl* ps)
{
	if (ps->arr != NULL)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
//顺序表的尾部插入数据
void slpushback(sl* ps, sldatatype x)
{
	//对传进来的指针进行断言
	assert(ps);
	//判断数组大小和空间的容量是否相同
	check(ps);
	ps->arr[ps->size] = x;
	ps->size++;
}
//顺序表的头部插入数据
void slpushfront(sl* ps, sldatatype x)
{
	assert(ps);
	check(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}
//顺序表的打印
//void slprint(sl s)
//{
//	for (int i = 0; i < s.size; i++)
//	{
//		printf("%d ", s.arr[i]);
//	}
//	printf("\n");
//}
//顺序表的尾删
void slpopback(sl* ps)
{
	assert(ps);
	assert(ps->size);//如果我们顺序表本来就没有数据,我们进行减减就会变为-1了,显然不对,进行断言
	ps->size--;//渐渐就减少了范围,直接把最后的元素删除,就相当于最后一个元素不属于顺序表了
}
//顺序表的头删
void slpopfront(sl* ps)
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//最后是arr[size-2]=arr[size-1];
	}
	ps->size--;
}

//顺序表的指定位置之前插入
void slinsert(sl* ps, int pos, sldatatype x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	check(ps);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}

//顺序表的指定删除
void slerase(sl* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

//顺序表的数据的查找
//int slfind(sl* ps, sldatatype x)
//{
//	assert(ps);
//	for (int i = 0; i < ps->size; i++)
//	{
//		//找到了
//		if (ps->arr[i] == x)
//		{
//			return i;
//		}
//	}
//	//没有找到
//	return -1;//无效的下标
//}

(3)contact.h

#pragma once
#define name_max 20
#define gender_max 10
#define tel_max 20
#define addr_max 20
typedef struct personinfo
{
	char name[name_max];
	char gender[gender_max];
	int age;
	char tel[tel_max];
	char addr[addr_max];
}perinfo;

typedef struct seqlist contact;
//通讯录初始化
void contactinit(contact* con);
//通讯录销毁
void contactdestory(contact* con);
//通讯录添加联系人数据
void contactadd(contact* con);
//通讯录删除联系人数据
void contactdel(contact* con);
//通讯录修改联系人数据
void contactmodify(contact* con);
//通讯录查找联系人数据
void contactfind(contact* con);
//通讯录展示联系人数据
void contactshow(contact* con);

(4)contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
#include"seqlist.h"
void contactinit(contact* con)
{
	slinit(con);
}

void contactdestory(contact* con)
{
	sldestory(con);
}

void contactadd(contact* con)
{
	perinfo info;
	printf("请输入联系人的姓名:\n");
	scanf("%s", info.name);
	printf("请输入联系人的性别:\n");
	scanf("%s", info.gender);
	printf("请输入联系人的年龄:\n");
	scanf("%d", &info.age);
	printf("请输入联系人的电话:\n");
	scanf("%s", info.tel);
	printf("请输入联系人的地址:\n");
	scanf("%s", info.addr);

	slpushback(con, info);
}

int findbyname(contact* con, char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			//说明找到了
			return i;
		}
	}
	return -1;
}
void contactdel(contact* con)
{
	char name[name_max];
	printf("请输入要删除的联系人的姓名:\n");
	scanf("%s", name);

	int find = findbyname(con, name);
	if (find < 0)
	{
		printf("要删除的联系人的数据不存在\n");
		return;
	}
	//删除的联系人的数据存在
	slerase(con, find);
	printf("删除成功 !\n");
}

void contactmodify(contact* con)
{
	char name[name_max];
	printf("请输入要修改的联系人的姓名:\n");
	scanf("%s", name);

	int find = findbyname(con, name);
	if (find < 0)
	{
		printf("要修改的联系人的数据不存在\n");
		return;
	}

	printf("请输入新的联系人的姓名:\n");
	scanf("%s", con->arr[find].name);
	printf("请输入新的联系人的性别:\n");
	scanf("%s", con->arr[find].gender);
	printf("请输入新的联系人的年龄:\n");
	scanf("%d", &con->arr[find].age);
	printf("请输入新的联系人的电话:\n");
	scanf("%s", con->arr[find].tel);
	printf("请输入新的联系人的地址:\n");
	scanf("%s", con->arr[find].addr);

	printf("修改成功\n");
}

void contactfind(contact* con)
{
	char name[name_max];
	printf("请输入要查找的联系人的姓名:\n");
	scanf("%s", name);

	int find = findbyname(con, name);
	if (find < 0)
	{
		printf("要查找的联系人的数据不存在\n");
		return;
	}
	printf("查找成功\n");

	printf("%s  %s  %s  %s  %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%s    %s    %d    %s    %s\n",
			con->arr[find].name,
			con->arr[find].gender,
			con->arr[find].age,
			con->arr[find].tel,
			con->arr[find].addr);
	}
}

void contactshow(contact* con)
{
	printf("%s  %s  %s  %s  %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < con->size; i++)
	{
		printf("%s    %s    %d    %s    %s\n",
			con->arr[i].name,
			con->arr[i].gender,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr);
	}
}

(5)test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"seqlist.h"
//void sltest01()
//{
//	sl sl1;
//
//	//顺序表的初始化
//	slinit(&sl1);
//
//	//顺序表的尾部插入数据
//	slpushback(&sl1, 8);
//	slpushback(&sl1, 9);
//	slpushback(&sl1, 10);
//	slpushback(&sl1, 11);
//
//	//尾部插入之后打印
//	slprint(sl1);
//
//	//顺序表的头部插入数据
//	slpushfront(&sl1, 5);
//	slpushfront(&sl1, 6);
//
//	//头部插入之后打印
//	slprint(sl1);
//
//	//顺序表的尾删
//	slpopback(&sl1);
//	slprint(sl1);
//
//	//顺序表的头删
//	slpopfront(&sl1);
//	slprint(sl1);
//
//	//顺序表的指定位置之前插入
//	slinsert(&sl1, 1, 0);
//	slprint(sl1);
//
//	//顺序表的指定删除
//	slerase(&sl1, 1);
//	slprint(sl1);
//
//	//顺序表的数据的查找
//	int ret = slfind(&sl1, 100);
//	if (ret < 0)
//	{
//		printf("没有找到\n");
//	}
//	else
//	{
//		printf("找到了,下标是%d\n", ret);
//	}
//	//顺序表的销毁
//	sldestory(&sl1);
//}

//void contacttest01()
//{
//	contact con;
//	contactinit(&con);
//
//	contactadd(&con);
//	contactadd(&con);
//	contactshow(&con);
//
//	contactdel(&con);
//	contactshow(&con);
//
//	contactmodify(&con);
//	contactshow(&con);
//
//	contactfind(&con);
//
//
//	contactdestory(&con);
//}

void menu()
{
	printf("*************通讯录*************\n");
	printf("*****1、添加用户 2、删除用户****\n");
	printf("*****3、修改用户 4、查找用户****\n");
	printf("*****5. 展示用户 0.退出通讯录***\n");
	printf("********************************\n");
}
int main()
{
	//顺序表的功能测试函数
	//sltest01();
	/*contacttest01();*/
	int input = -1;
	contact con;
	contactinit(&con);
	do
	{
		menu();
		printf("请选择");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			contactadd(&con);
			break;
		case 2:
			contactdel(&con);
			break;
		case 3:
			contactmodify(&con);
			break;
		case 4:
			contactfind(&con);
			break;
		case 5:
			contactshow(&con);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
	contactdestory(&con);
	return 0;
}

内容概要:文章基于4A架构(业务架构、应用架构、数据架构、技术架构),对SAP的成本中心和利润中心进行了详细对比分析。业务架构上,成本中心是成本控制的责任单元,负责成本归集与控制,而利润中心是利润创造的独立实体,负责收入、成本和利润的核算。应用架构方面,两者都依托于SAP的CO模块,但功能有所区分,如成本中心侧重于成本要素归集和预算管理,利润中心则关注内部交易核算和获利能力分析。数据架构中,成本中心与利润中心存在多对一的关系,交易数据通过成本归集、分摊和利润计算流程联动。技术架构依赖SAP S/4HANA的内存计算和ABAP技术,支持实时核算与跨系统集成。总结来看,成本中心和利润中心在4A架构下相互关联,共同为企业提供精细化管理和决策支持。 适合人群:从事企业财务管理、成本控制或利润核算的专业人员,以及对SAP系统有一定了解的企业信息化管理人员。 使用场景及目标:①帮助企业理解成本中心和利润中心在4A架构下的运作机制;②指导企业在实施SAP系统时合理配置成本中心和利润中心,优化业务流程;③提升企业对成本和利润的精细化管理水平,支持业务决策。 其他说明:文章不仅阐述了理论概念,还提供了具体的应用场景和技术实现方式,有助于读者全面理解并应用于实际工作中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值