Day22.C提高6

Day22.C提高6

一、函数指针

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void func101()
{
	printf("hello world\n");
}


//函数名其实就是函数的入口地址
void test101()
{
	//printf("函数入口地址:%d", func101);
	int* funcAddr = (int*)func101;
	void(*myfunc)() = (void(*)())funcAddr;
	myfunc();
	
	
}

int func102(int a, char b)
{
	printf("a:%d b:%c\n", a, b);
	return 0;
}
//如何去定义一个指向函数的指针
void test102()
{
	//1.定义函数类型,通过类型来定义函数指针
	typedef int(FUN_TYPE)(int, char);
	FUN_TYPE* pFunc = func102;
	pFunc(10, 'a');
	(*pFunc)(20, 'b');
	func102(30, 'c');

	//2.直接定义函数指针类型
	typedef int(*FUN_P)(int, char);
	FUN_P pFunc2 = func102;
	pFunc2(40, 'd');

	//3.直接定义函数指针变量
	int (*pFunc3)(int, char) = NULL;
	pFunc3 = func102;
	pFunc3(50, 'e');
	
	//注:函数指针指向相同类型

	//把指针转换为函数指针类型写法
	int* pFunc4 = NULL;
	(int(*)(int, char))pFunc4 = func102;
	//void* pFunc4 = (int(*)(int, char))NULL;
	//pFunc4 = func102;
	pFunc(60, 'f');

}

//函数指针数组
void func1()
{
	printf("func1\n");
}
void func2()
{
	printf("func2\n");
}
void func3()
{
	printf("func3\n");
}

void test103()
{
	//函数指针数组定义方式
	//先定义一个函数指针数组
	void (*pFunc_Array[3])();
	//给函数指针数组中的值进行赋值
	pFunc_Array[0] = func1;
	pFunc_Array[1] = func2;
	pFunc_Array[2] = func3;
	//调用
	for (int i = 0; i < 3; i++)
	{
		pFunc_Array[i]();
	}
}

//函数指针作函数参数(回调函数)
void printALLArray(void* arr, int eleSize, int len, void(*print)(void*))
{
	char* start = (char*)arr;
	//产生第i个元素的首地址,交给用户自定义的print函数来使用
	for (int i = 0; i < len; ++i)
	{
		char* eleAddr = start + i * eleSize;
		print(eleAddr);
	}

}

void MyPrint(void* data)
{
	int* p = (int*)data;
	printf("%d\n", *p);
}

struct Person 
{
	char name[64];
	int age;
};


//C语言不支持函数重载(C语言中函数名不可以重复)
void MyPrint_persons(void* data)
{
	struct Person* p = (struct Person*)data;
	printf("name:%s  age:%d\n", p->name, p->age);
}

//函数指针作函数参数
void test104()
{
	int arr[] = { 1,2,3,4,5 };
	printALLArray(arr, sizeof(int), 5, MyPrint);

	struct Person persons[] =
	{
		{"aaa",10},
		{"bbb",20},
		{"ccc",30},
		{"ddd",40},
	};
	printALLArray(persons, sizeof(struct Person), 4, MyPrint_persons);
}
int main(void)
{
	//test101();
	//test102();
	//test103();
	test104();


	system("pause");
	return EXIT_SUCCESS;
}

二、链表的基本概念

链表基本概念:
	
	链表是一种常用的数据结构,它通过指针将一些数据结点,连接成一个数据域。
	链表由一系列结点组成,每个结点包含两个域,一个是数据域,数据域用来保存用户数据。另外一个是指针域,用来建立与下一个结点的联系(保存下一个结点的地址)。链表的内存是非连续的。

属性:	1.拿到链表的第一个结点,就相当于拿到了整个链表
		2.头结点不保存任何数据
		3.建立链表时无需预先知道数据总量,可以随机的分配空间,可以高效的在来弄表中的任意位置实时插入或删除数据

链表数组的优缺点比较:

	数组优点:
	
		可以用下标来查找数据,随机访问元素效率高。
	
	数组缺点:
	
		1.需要分配一块连续的存储区域(很大区域,有可能分配失败)
		2.删除和插入某个元素效率低(在指定位置插入和删除会导致元素大量移动)。
		
	
	链表优点(无需一次性分配一块连续的存储区域,只需分配n块结点存储区域,通过指针建立关系):
		
		1.不需要一块连续的存储区域
		2.删除和插入某个元素效率高(链表在指定位置插入和删除不需要移动元素,只需要修改指针即可)。
		
	链表缺点:
		
		访问的顺序性和组织链的空间损失:
			随机访问元素效率低
			相对于数组来讲,多了指针空间的开销。

三、链表分类

带头和不带头链表:

	带头链表:固定一个结点作为头结点(数据与不保存有效数据),起一个标志位的作用,以后不管链表结点如何改变,此头结点固定不变。

	不带头链表:头结点不固定,根据实际需要变换头结点(如在原来头结点前插入新的结点,然后,新结点作为链表的头结点)

静态链表、动态链表
单向链表、双向链表、循环链表、单项循环链表、双向循环链表

四、静态链表

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//链表结点类型定义
struct LinkNode
{
	int data;
	struct LinkNode* next;
};

void test201()
{
	struct LinkNode node1 = { 10,NULL };
	struct LinkNode node2 = { 20,NULL };
	struct LinkNode node3 = { 30,NULL };
	struct LinkNode node4 = { 40,NULL };
	struct LinkNode node5 = { 50,NULL };
	struct LinkNode node6 = { 60,NULL };

	node1.next = &node2;
	node2.next = &node3;
	node3.next = &node4;
	node4.next = &node5;
	node5.next = &node6;

	//如何遍历整个链表?

	//先定义一个辅助指针变量
	struct LinkNode* pCurrent = &node1;
	while (pCurrent != NULL)
	{
		printf("%d ", pCurrent->data);

		//指针移动到下一个结点的首地址
		pCurrent = pCurrent->next;
	}
}

int main(void)
{
	test201();


	system("pause");
	return EXIT_SUCCESS;
}

五、动态链表(分文件编写)

动态链表:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkList.h"

void test301()
{
	//初始化链表100 200 666 300 400 500 600
	struct LinkNode* header = Init_LinkList();
	//打印链表
	Foreach_LinkList(header);
	//插入数据
	InsertByValue_LinkList(header, 300, 666);
	//打印链表
	printf("\n------------------\n");
	Foreach_LinkList(header);
	//删除666
	RemoveByValue_LinkList(header, 666);
	//打印链表
	printf("\n------------------\n");
	Foreach_LinkList(header);
	//清空链表
	Clear_LinkList(header);
	//插入数据111 222 333 444
	InsertByValue_LinkList(header, 1000, 111);
	InsertByValue_LinkList(header, 1000, 222);
	InsertByValue_LinkList(header, 1000, 333);
	InsertByValue_LinkList(header, 1000, 444);
	//打印链表
	printf("\n------------------\n");
	Foreach_LinkList(header);
	//删除333
	RemoveByValue_LinkList(header, 333);
	//打印链表
	printf("\n------------------\n");
	Foreach_LinkList(header);
	//删除443(链表中没有443)
	RemoveByValue_LinkList(header, 443);
	//打印链表
	printf("\n------------------\n");
	Foreach_LinkList(header);
	//销毁链表
	Destroy_LinkList(header);
}


int main(void)
{
	test301();


	system("pause");
	return EXIT_SUCCESS;
}

LinkList.h

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#ifdef __cplusplus
extern "C" {
#endif

	//定义结点数据类型
	struct LinkNode
	{
		int data;
		struct LinkNoda* next;
	};

	//初始化链表
	struct LinkNode* Init_LinkList();
	//在值为oldval的位置插入一个新的数据newval
	void InsertByValue_LinkList(struct LinkNode* header, int oldval, int newval);
	//删除值为delValue的结点
	void RemoveByValue_LinkList(struct LinkNode* header, int delValue);
	//遍历链表
	void Foreach_LinkList(struct LinkNode* header);
	//销毁链表
	void Destroy_LinkList(struct LinkNode* header);
	//清空链表
	void Clear_LinkList(struct LinkNode* header);



#ifdef __cplusplus
}
#endif

LinkList.c

#include"LinkList.h"



//初始化链表
struct LinkNode* Init_LinkList()
{
	//创建头结点
	struct LinkNode* header = malloc(sizeof(struct LinkNode));
	header->data = -1;
	header->next = NULL;

	//尾部指针
	struct LinkNode* pRear = header;
	

	//插入新的结点
	int val = -1;
	while (1)
	{
		printf("输入插入的数据:\n");
		scanf("%d", &val);
		if (val == -1)
		{
			break;
		}
		//先创建新节点
		struct LinkNode* newnode = malloc(sizeof(struct LinkNode));
		newnode->data = val;
		newnode->next = NULL;
		//新节点插入到链表中
		pRear->next = newnode;
		//更新尾部指针指向
		pRear = newnode;
	}
	return header;
}

//在值为oldval的位置插入一个新的数据newval
void InsertByValue_LinkList(struct LinkNode* header, int oldval, int newval)
{
	if (NULL == header)
	{
		return;
	}
	//两个辅助指针变量
	struct LinkNode* pPrev = header;
	struct LinkNode* pCurrent = pPrev->next;

	while (pCurrent != NULL)
	{
		if (pCurrent->data == oldval)
		{
			break;
		}
		pPrev = pCurrent;
		pCurrent = pPrev->next;
	}

	//如果pCurrent为NULL,说明链表中不存在值为oldval的结点
	//写上此if语句,若不存在值为oldval的结点,则不做操作
	//不写此语句,若不存在值为oldval的结点,将newval添加到链表最后
	//if (pCurrent == NULL)
	//{
	//	return;
	//}

	//先创建新节点
	struct LinkNode* newnode = malloc(sizeof(struct LinkNode));
	newnode->data = newval;
	newnode->next = NULL;

	//新结点插入到链表中
	pPrev->next = newnode;
	newnode->next = pCurrent;
}

//删除值为delValue的结点
void RemoveByValue_LinkList(struct LinkNode* header, int delValue)
{
	if (NULL == header)
	{
		return;
	}
	//创建两个辅助指针变量
	struct LinkNode* pPrev = header;
	struct LinkNode* pCurrent = pPrev->next;

	while (pCurrent != NULL)
	{
		if (pCurrent->data == delValue)
		{
			break;
		}
		//移动两个辅助指针
		pPrev = pCurrent;
		pCurrent = pPrev->next;

	}
	//如果pCurrent为NULL,说明链表中不存在值为delValue的结点
	if (pCurrent == NULL)
	{
		return;
	}
	//重新建立待删除结点的前驱和后继结点关系
	pPrev->next = pCurrent->next;
	//释放删除结点的内存空间
	free(pCurrent);
	pCurrent = NULL;

}

//遍历链表
void Foreach_LinkList(struct LinkNode* header)
{
	if (NULL == header)
	{
		return;
	}

	//辅助指针变量
	struct LinkNode* pCurrent = header->next;
	while (pCurrent != NULL)
	{
		printf("%d ", pCurrent->data);
		pCurrent = pCurrent->next;
	}
}

//销毁链表
void Destroy_LinkList(struct LinkNode* header)
{
	if (NULL == header)
	{
		return;
	}
	//辅助指针变量
	struct LinkNode* pCurrent = header;
	while (pCurrent != NULL)
	{
		//先保存一下当前结点的下一个结点地址
		struct LinkNode* pNext = pCurrent->next;

		//释放当前结点内存
		free(pCurrent);
		pCurrent = NULL;
		//pCurrent指向下一个结点
		pCurrent = pNext;
	}
	
}

//清空链表
void Clear_LinkList(struct LinkNode* header)
{
	if (NULL == header)
	{
		return;
	}
	//辅助指针变量
	struct LinkNode* pCurrent = header->next;
	while (pCurrent != NULL)
	{
		//先保存一下当前结点的下一个结点地址
		struct LinkNode* pNext = pCurrent->next;

		//释放当前结点内存
		free(pCurrent);
		pCurrent = NULL;
		//pCurrent指向下一个结点
		pCurrent = pNext;
	}
	header->next = NULL;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
综合小区管理系统管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、车位管理、车位分配管理、出入管理、字典管理、房屋管理、物业费缴纳管理、公告管理、物业人员投诉管理、我的私信管理、物业人员管理、用户管理、管理员管理。用户的功能包括管理部门以及部门岗位信息,管理招聘信息,培训信息,薪资信息等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 综合小区管理系统管理系统可以提高综合小区管理系统信息管理问题的解决效率,优化综合小区管理系统信息处理流程,保证综合小区管理系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理综合小区管理系统信息,包括出入管理,报修管理,报修管理,物业费缴纳等,可以管理操作员。 出入管理界面,管理员在出入管理界面中可以对界面中显示,可以对招聘信息的招聘状态进行查看,可以添加新的招聘信息等。报修管理界面,管理员在报修管理界面中查看奖罚种类信息,奖罚描述信息,新增奖惩信息等。车位管理界面,管理员在车位管理界面中新增。公告管理界面,管理员在公告管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值