【C语言】函数进阶

【C语言】函数进阶


文章目录


前言

本篇文章我们会讲到有关函数的相关知识,函数指针的定义方式,函数指针数组,函数指针做函数参数,回调函数,递归函数。


一、函数指针的定义方式

  • 函数指针 和 指针函数 区别?
    函数指针 指向了函数的指针
    指针函数 函数返回值是指针的函数
c 复制代码
void func(int a, char c)
{
	printf("hello world\n");
}

void test01()
{
	//1、先定义出函数类型,在通过类型定义函数指针
	typedef void(FUNC_TYPE)(int, char);

	FUNC_TYPE* pFunc = func;
	pFunc(10, 'a');

	//2、定义出函数指针类型,通过类型定义函数指针变量
	typedef void(*FUNC_TYPE2)(int, char);
	FUNC_TYPE2 pFunc2 = func;
	pFunc2(20, 'b');

	//3、直接定义函数指针变量
	void(*pFunc3)(int, char) = func;
	pFunc3(30, 'c');

}

二、函数指针数组

c 复制代码
//函数指针的数组
void func1()
{
	printf("func1 调用了\n");
}

void func2()
{
	printf("func2 调用了\n");
}

void func3()
{
	printf("func3 调用了\n");
}

void test02()
{
	void(*pArray[3])();

	pArray[0] = func1;
	pArray[1] = func2;
	pArray[2] = func3;

	for (int i = 0; i < 3; i++)
	{
		pArray[i]();
	}
}

三、函数指针做函数参数

提供一个打印函数,可以打印任意类型的数据

c 复制代码
//提供一个打印函数,可以打印任意类型的数据
void printText(void* data, void(*myPrint)(void*))
{
	myPrint(data);
}

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



void test01()
{
	int a = 10;
	printText(&a, myPrintInt); 
}


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


void myPrintPerson(void* data)
{
	struct Person* p = data;
	printf("姓名: %s 年龄:%d\n", p->name, p->age);
}


void test02()
{
	struct Person p = { "Tom",18 };
	printText(&p, myPrintPerson);

}

四、回调函数

提供一个函数,实现可以打印任意类型的数组

c 复制代码
//提供一个函数,实现可以打印任意类型的数组 
void printAllArray(void* pArray, int eleSize, int len, void(*myPrint)(void*))
{
	char* p = pArray;

	for (int i = 0; i < len; i++)
	{
		//获取数组中每个元素的首地址
		char* eleAddr = p + eleSize * i;
		//printf("%d\n", *(int *)eleAddr);
		//交还给用户做打印操作
		myPrint(eleAddr);
	}

}

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

void test01()
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	int len = sizeof(arr) / sizeof(int);
	printAllArray(arr, sizeof(int), len, myPrintInt);
}


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

void myPrintperson(void* data)
{
	struct Person* p = data;
	printf("姓名:%s  年龄:%d \n", p->name, p->age);
}

//查找数组中的元素是否存在
//参数1  数组首地址   参数2  每个元素的大小  参数3  数组元素个数  参数4 查找数据
int findArrayEle(void* pArray, int eleSize, int len, void* data, int(*myCompare)(void*, void*))
{
	char* p = pArray;

	for (int i = 0; i < len; i++)
	{
		//每个元素的首地址
		char* eleAddr = p + eleSize * i;

		//if ( 数组中的变量的元素 == 用户传入的元素)
		if (myCompare(eleAddr, data))
		{
			return 1;
		}
	}

	return 0;

}
int myComparePerson(void* data1, void* data2)
{
	struct Person* p1 = data1;
	struct Person* p2 = data2;

	//if ( strcmp( p1->name , p2->name) == 0  &&  p1->age == p2->age)
	//{
	//	return 1;
	//}
	//return  0;

	return   strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;

}



void test02()
{
	struct Person personArray[] =
	{
		{ "aaa", 10 },
		{ "bbb", 20 },
		{ "ccc", 30 },
		{ "ddd", 40 },
	};
	int len = sizeof(personArray) / sizeof(struct Person);
	printAllArray(personArray, sizeof(struct Person), len, myPrintperson);

	//查找数组中指定的元素是否存在
	struct Person p = { "ccc", 30 };

	int ret = findArrayEle(personArray, sizeof(struct Person), len, &p, myComparePerson);

	if (ret)
	{
		printf("找到了元素\n");
	}
	else
	{
		printf("未找到\n");
	}
}

五、递归函数

利用递归实现字符串逆序遍历
斐波那契数列

c 复制代码
//利用递归实现字符串逆序遍历
void reversePrint(char* p)
{
	if (*p == '\0')
	{
		return;
	}

	reversePrint(p + 1);

	printf("%c\n", *p);

}
void test01()
{
	char* str = "abcdefg";
	reversePrint(str);
}

int fibonacci(int pos) 
{
	if (pos == 1 || pos == 2)
	{
		return 1;
	}

	return fibonacci(pos - 1) + fibonacci(pos - 2);
}
void test02()
{
	//斐波那契数列
	// 1 1 2 3 5 8 13 21  34  55...
	printf("第9为数字为:%d\n", fibonacci(9)); 
	printf("第10为数字为:%d\n", fibonacci(10));
	printf("第20为数字为:%d\n", fibonacci(20));

}

总结

到这里这篇文章的内容就结束了,谢谢大家的观看,如果有好的建议可以留言喔,谢谢大家啦!

相关推荐
知识分享小能手36 分钟前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
TomCode先生1 小时前
c#动态树形表达式详解
开发语言·c#
高-老师2 小时前
基于R语言的物种气候生态位动态量化与分布特征模拟
开发语言·r语言·物种气候
大翻哥哥2 小时前
Python 2025:量化金融与智能交易的新纪元
开发语言·python·金融
weixin_437830943 小时前
使用冰狐智能辅助实现图形列表自动点击:OCR与HID技术详解
开发语言·javascript·ocr
鹿鹿学长3 小时前
2025年全国大学生数学建模竞赛(C题) 建模解析|婴儿染色体数学建模|小鹿学长带队指引全代码文章与思路
c语言·开发语言·数学建模
伴杯猫3 小时前
【ESP32-IDF】基础外设开发2:系统中断矩阵
c语言·单片机·嵌入式硬件·mcu·物联网·github
zhousenshan3 小时前
Python爬虫常用框架
开发语言·爬虫·python
茯苓gao3 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾4 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang