首页 > 其他分享 >C语言中有关函数的知识

C语言中有关函数的知识

时间:2024-09-06 21:52:00浏览次数:12  
标签:return 函数 递归 int 知识 ret C语言 printf

        前言

        C语言函数是一种函数,用来编译C语言,一般包括字符库函数,数学函数,目录函数,进程函数,诊断函数,操作函数等

        这里这个函数和我们高中时期学的函数类似,高中的函数是这样

        F(x)=5x+21                

        这里是在括号里输入x,输出F(x)计算的值

        比如这里输入100,那么结果就是521

        在C语言中函数也是这样的

int add(int x)
{

        return y=5x+21;

}
 

        同样都是给函数输入x的值,输出y

函数的运用        

        C语言中把函数分为两类,一类是库函数,另一类是自定义函数

        1.1 库函数

        库函数就是在C语言中已经有的一些函数,比如:printf()、scanf()、srtlne()……但是要调用这些函数的时候我们需要先在程序最开头交代一下用到的库函数对应#include的头文件,这就是为什么我们现在的程序第一排都有#include<stdio.h>,是因为printf、scanf这两个库函数的头文件是他。

        想学习其他更多的库函数可以去http://www.cplusplus.com/reference/

        1.2 自定义函数

        一定不能当白嫖怪呀!如果所有的操作全都在库函数里面可以直接调用的话,那还要程序员干什么。因此我们也要学会写我们自己的函数。自定义函数和库函数一样,有函数名,返回值类型和函数参数。 但是不一样的是这些都是我们自己来设计。这给我们一个很大的发挥空间
 

int fun_name(int x)

{
    printf("haha\n");
}

int 返回类型

fun_name 函数名

int x 函数参数

        于是我们就可以用函数来干很多事情了(先以最简单的比大小来当例子)

int get_max(int x, int y)
{
	return x > y ? x: y;
}

int main()
{
	int a = 0;
	int b = 0;
	int max = 0;
	scanf("%d %d", &a, &b);
	max = get_max(a, b);
	printf("%d", max);
	return 0;
}

        再来一个例子,将输入的数字互换位置

//错误的交换这里的“a”“b”并不是主函数中的“a”“b”
//所以这里函数里面看似交换了ab的值,但是主函数里面还是没有

void swap(int a, int b)
{
	int tmp = 0;
	tmp = a;
	a = b;
	b = tmp;
	return 0;
}

//正确的交换:直接用变量“a”“b”的地址进行交换

void swap(int* a, int* b)
{
	int tmp = 0;
	tmp = *a;
	*a = *b;
	*b = tmp;
	return 0;
}

int main()
{
	int a = 0;
	int b = 0;
	printf("交换前:");
	scanf("%d %d", &a, &b);
	swap(&a, &b);
	printf("交换后:%d %d\n",a,b);
	return 0;
}

递归思想

        开始上强度,知道函数的基本概念之后,我们就要学一个新的东西:函数递归

        循环有两种方式,一个是迭代,另一个就是递归

        2.1 递归是什么

        给大家讲一个故事:从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,讲的是:从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,讲的是:从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,讲的是:……

        这个故事就是一个递归

        递归是不断调用自身,假设递自己是一个函数的话,那递的返回值会当作参数再次传入自身。 迭代是将某一个初值设定,不断放入某一个循环体,得到的值成为一个新值再次放入循环体中,通过循环体中的操作,逐步得到我们想要的结果。

        迭代是人的思考方式,而递归是神的思考方式

         理解递归是我们封神的第一步

        程序调用自身的编程技巧称为递归( recursion)。 递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接 调用自身的 一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解, 递归策略 只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。 递归的主要思考方式在于:把大事化小

        递归,顾名思义需要先递推再回归,就是先一步步把难解决的问题递推到简单好处理的问题上,在再一步步反推上去,最终计算出全部的结果。

        其实我们在高中时期就遇到过递归思想:证明数列时用到的数学归纳法就是其中之一

最简单和常见的数学归纳法是证明当n等于任意一个自然数时某命题成立。证明分下面两步:

1.证明当n= 1时命题成立。

2.假设n=m时命题成立,那么可以推导出在n=m+1时命题也成立。(m代表任意自然数)

        2.2 递归的两个必要条件

        1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。

        2.每次递归调用之后越来越接近这个限制条件。

        满足上面的条件递归函数不一定正确,但是不满足上面两个条件的函数递归一定是错的

        2.3 递归的运用

        接受一个整型值(无符号),按照顺序打印它的每一位。

void print(int a)
{
	if (a > 9)
	{
		print(a / 10);
	}
		printf("%d ", a%10);
}

int main()
{
	int a = 5678;
	print(a);
	return 0;
}

        程序运行的原理图如下: 

        这里可以看到print函数不断调用自己打印出对应的数字,这就是递归

        再来一题练练手

        编写一个函数实现n的k次方,使用递归实现

int my_pow(int n, int k)
{
	if (k > 0)
		return n * my_pow(n, k - 1);
	return 1;
}

int main()
{
	int n = 0;
	int k = 0;
	int ret = 0;
	printf("请输入n k:");
	scanf("%d %d", &n, &k);
	ret = my_pow(n,k);
	printf("%d的%d次方为:%d\n", n, k, ret);
	return 0;
}

这个问题也可以用循环来解决:

int my_pow(int n, int k)
{
	int  i = 0;
	int ret = 1;
	for (i = 0; i < k; i++)
	{
		ret = ret * n;
	}
	return ret;
}

int main()
{
	int n = 0;
	int k = 0;
	int ret = 0;
	printf("请输入n k:");
	scanf("%d %d", &n, &k);
	ret = my_pow(n,k);
	printf("%d的%d次方为:%d\n", n, k, ret);
	return 0;
}

        这里的循环其实就是迭代,我们可以从中看出迭代和递归两个方法的优缺点:

        1. 许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。

        2. 但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差些。

        3. 当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销。

        2.4 汉诺塔问题

         汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

        求当有n个圆盘的时候,需要挪动的最少步数x

        这个问题一样可以用递归来解决

        如果只有一个圆盘的时候,只需要一步就能解决问题,如果我们把计算步数的函数命名为hannuo()   

也就是hannuo(1)=1

        如果有两个圆盘,

        就先变成一个大圆盘加上一个小圆盘,

        再把大圆盘移到其他柱子上,

        最后把小圆盘移到大圆盘上

        显然需要3步     

        那么这里就是hannuo(2)=hannuo(1)+1+hannuo(1)=3

        我们继续把圆盘的数量增加到3个

        第一步:先把整体分为大圆盘+n-1个圆盘(步数为:hannuo(2))

        第二步:把大圆盘换位置(步数为:1)

        第三步:再把这n-1个圆盘移到大圆盘上(步数为:hannuo(2))

        所以总步数为:hannuo(3)=hannuo(2)+1+hannuo(2)

        相信聪明的你已经发现规律了,那么为n个圆盘的时候呢?

        hannuo(n)=2hannuo(n-1)+1

        这就是一个典型的递归思想

        代码为:

int hannuo(int n)
{
	if (n > 1)
		return 2*hannuo(n-1)+1;
	return 1;
}

int main()
{
	int n = 0;
	printf("请输入圆盘个数:");
	scanf("%d", &n);
	int x = hannuo(n);
	printf("%d个圆盘需要%d步\n", n, x);
	return 0;
}

        2.5 青蛙跳台阶问题

        题目为:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

 

        假设计算多少种跳法的函数命名为:ways(x)

        显然ways(1)=1,ways(2)=2

        如果有n级台阶的时候,我们把计算步数分为两大类:

        第一类:如果青蛙第一次只跳一级台阶,那么就还剩下n-1级台阶(ways(n-1)种跳法)

        第二类:如果青蛙第一次跳了二级台阶,那么就还剩下n-2级台阶(ways(n-2)种跳法)

        所以总的跳法就应该有ways(n)=ways(n-1)+ways(n-2)

        此时问题就被我们解决了,代码为:

int ways(int n)
{
	if (n > 2)
		return ways(n - 1) + ways(n - 2);
	else if (2 == n)
		return 2;
	else
		return 1;
}

int main()
{
	int n = 0;
	int ret = 0;
	printf("请输入青蛙要跳的台阶数n:");
	scanf("%d", &n);
	ret = ways(n);
	printf("青蛙一共有%d种跳法\n", ret);
	return 0;
}

        2.6 斐波那契数列

        斐波那契数列(Fibonacci sequence),又称黄金分割数列 [1],因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34……在数学上,这一数列以如下递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。

        其实上一个青蛙跳台阶问题就是斐波那契数列问题,我们除了用递归的方法来完成斐波那契数列,也可以用循环的方法:
 

int feibo(int n)
{
	int a = 1;
	int b = 1;
	int ret = 1;
	while (n > 2)
	{
		ret = a + b;
		a = b;
		b = ret;
		n--;
	}
	return ret;
}

int main()
{
	int n = 0;
	int ret = 0;
	printf("输入:");
	scanf("%d", &n);
	ret = feibo(n);
	printf("第%d个斐波那契数为:%d", n, ret);
	return 0;
}
 

        都看到这里了,还不给个小赞?QAQ

标签:return,函数,递归,int,知识,ret,C语言,printf
From: https://blog.csdn.net/m0_74779094/article/details/141945766

相关文章

  • C语言程序设计(初识C语言后部分)
    不要重来,不要白来,不要重来。5.指针和数组数组:一组相同类型元素的集合指针变量:是一个变量,存放的地址要理解数组名大部分情况下是数组的首元素地址6.二级指针先了解一级指针变量二级指针变量(二级指针变量是用来存放一级指针变量的地址的)7.指针数组指针数组是......
  • MySQL 日期函数语法介绍和案例示范以及常见问题解决
    本文将以电商交易系统为例,详细讲解MySQL日期类型及其转化,常用的日期函数,以及一些解决常见问题的方案。一、MySQL日期数据类型MySQL提供了多种日期数据类型,适用于不同的使用场景。常见的日期类型包括DATE、DATETIME、TIMESTAMP、TIME和YEAR。DATE:只存储日期,不包含......
  • C语言数据类型和变量
    引言好久不见大家,最近因为在忙开学的事情很久没有更新,很感谢大家的支持,我会继续努力滴!!!前篇链接:http://#小程序://CSDN/Rz9Z9VlUkPV8ttg那我们长话短说:开始我们的这一节--------C语言数据类型和变量数据类型介绍C语⾔提供了丰富的数据类型来描述⽣活中的各种数据。......
  • JavaScript学习文档(14):深入对象、内置构造函数、综合案例
    目录一、深入对象1、创建对象三种方式2、构造函数(1)构造函数(2)说明:(3)利用构造函数创建多个对象(4)实例化执行过程3、实例成员和静态成员(1)实例成员:(2)静态成员:二、内置构造函数1、Object2、Array(1)数组常见实例方法-核心方法(2)员工涨薪计算成本案例(3)还有些数组常见方法(4......
  • C语言——使用回调函数模拟实现qsort
    同学们还记得之前我们已经学过一种排序方法叫“冒泡排序“嘛。代码直接附上咯voidbubble_sort(intarr[],intsz){ inti=0;//趟数 for(i=0;i<sz-1;i++) { intj=0; for(j=0;j<sz-i-1;j++) { if(arr[j]>arr[j+1]) { inttmp=......
  • 【YashanDB知识库】修改字段长度后,jdbc驱动接口报YAS-04007 Message:result set metada
    问题现象yashandb修改表的字段长度后,客户的业务接口报YAS-04007异常,截图如下:问题的风险及影响客户的业务在访问yashandb时异常出错,影响使用问题影响的版本所有的yashandb版本问题发生原因使用jdbc接口获取PreparedStatement以后,修改表的字段长度,再用前面获取的PreparedStatement继......
  • C语言-第七章:字符和字符串函数、动态内存分配
    传送门:C语言-第六章-加餐:其他自定义类型目录第一节:字符和字符串函数    1-1.strlen函数和sizeof关键字    1-2.memcpy内存拷贝函数    1-3.memmove内存拷贝函数    1-4.memset内存设置函数    1-5.strtok字符串切割函数......
  • C语言-第六章-加餐:其他自定义类型
    传送门:C语言-第六章:结构体目录第一节:位段    1-1.位段是什么    1-2.位段的大小第二节:联合体    2-1.联合体是什么    2-2联合体的大小第三节:枚举类型    3-1.枚举是什么第四节:结构体中的柔性数组    4-1.柔性数组......
  • 掌握检索技术:构建高效知识检索系统的架构与算法6
    在检索专业知识层需要涵盖更高级的检索技术,包括工程架构和算法策略。一、工程架构工程架构在构建检索系统中决定了系统的可扩展性、高可用性和性能。比如需要考虑的基本点:分布式架构:水平扩展:采用分布式架构,将检索任务分布到多个节点上,实现水平扩展。这可以通过将索引数据......
  • C语言面向对象
    我们在编写程序时,通常采用以下步骤:将问题的解法分解成若干步骤使用函数分别实现这些步骤依次调用这些函数这种编程风格的被称作面向过程。除了面向过程之外,还有一种被称作面向对象的编程风格被广泛使用。面向对象采用基于对象的概念建立模型,对现实世界进行模拟,从而完......