C语言函数认识

文章介绍了C语言中的函数概念,包括函数作为程序的子程序,类比于汽车零件。库函数是预先封装好的功能,如`pow`函数,提供便利但需包含对应头文件。自定义函数则允许开发者根据需求创建自己的功能。文章讨论了函数的参数、调用方式(传值与传址),以及函数的嵌套调用和链式访问。此外,还提到了函数的声明与定义的分离,以及递归的概念,例如计算阶乘,递归需满足有限制条件并逐步接近目标问题。
摘要由CSDN通过智能技术生成

在C语言中,函数可以说是陪伴着我们成长的,那么我们今天来看看什么函数

1.函数是什么

函数在我们在数学中已经用到,但是在编写代码中又赋予了一些不同的意义,那就是程序的子程序,那么这个子程序我们怎么去理解呢,用一个形象的比喻其实就是,把整个程序比作一个汽车,函数就是这个汽车中的零件,由很多的函数一起构成了整个程序。

而函数又分为了库函数自定义函数

2.库函数

库函数是什么呢,库函数是谁写的呢?让我们带着疑问看看。

库函数其实就是一些封装好的函数,给使用者提供了极大的便利,让我们可以直接使用现成的函数就可以实现一些功能,不需要我们自己再去实现这个函数。

库函数很多人以为是C语言语法自己带着的,其实并不是,他是众多编译器厂商一起讨论实现定义的 ,虽然他们里面实现的内容不太一样,但是最后想要得到的结果和大体相同的

让我们来看几个库函数:

#include <math.h>

void Test()
{
	int n = (int)pow(2, 5);
	printf("%d ", n);
}

 通过我们去查找文档仔细阅读后,看到了两个参数,一个是double 的底数 ,一个数double的次方数,返回值为double,知道了这些,我们去看上方代码,我们得到的N就是我们要的结果,通过调用库函数,就可以直接使用,极大便利了我们,当然了,在调用库函数的时候一定要调用头文件。

3.自定义函数

有人说,有了库函数就可以了啊,为什么要自定义函数。这我就不得不说了,如果库函数把所以的事情都干了,那么要程序员干什么呢,有了自定义函数,才让我们有了很大的发挥空间。

让我们看看自定义函数

ret_type fun_name(type paral)
	{
	       ......内容
	   }

这就是自定义函数的形式  ret_type 是函数的返回类型 fun_name 函数名 type paral 函数参数

{}里面写函数内容。

MAX函数示例:

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

void Test2()
{
	int a = 10;
	int b = 20;
	int ret = Max(a,b);
	printf("%d ", ret);
}

我实现了一个简单的自定义函数Max,int 就是函数返回值的类型为int .Max是函数名字,int x,int y是函数的参数(形参)。 

4.函数的参数 

实参:常量,变量,表达式,函数

让我们看上面的MAX函数示例,Test函数中,Max(a,b)中a,b就是实际参数

形参:用来接收实参,需要写出类型和接收变量。需要与实参匹配,比如实参是int 那么形参也需要是int 类型匹配,如果实参传的是地址,那么形参就必须是指针。

当然,形参是实参的一份零时拷贝,如果没有调用,那么形参并不会开辟空间。

并且形参的生命是随着这个函数生命一起结束销毁的。

让我们看上面的MAX函数示例,Max函数中,x,y就是形参。

5.函数的调用

 函数的调用分为传值调用和传址调用。让我们来看两个函数来理解

void Swap(int x,int y)
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
	
}

void Test3()
{
	int a = 10;
	int b = 20;
	Swap(a, b);
	printf("%d %d",a,b);
}

上方的Swap我想要实现的是交换两个值 ,但是我们发现,x,y 的值交换了,但是a,b的值并没有交换,这是因为我们用的是传值调用,只是单单把a,b的数值拷贝了一份传给了x,y。在Swap中交换了x,y后,并不会影响原值a,b。通俗的说,就是复印件的改变并不会影响原件

void Swap(int* x,int* y)
{
	int tmp = 0;
	tmp = *x;
	*x = *y;
	*y = tmp;
	
}

void Test4()
{
	int a = 10;
	int b = 20;
	Swap(&a, &b);
	printf("%d %d",a,b);
}

那么再看修改后的Swap函数,这个函数打印后我们发现,a.b的值发生了交换,这是为什么呢。

因为我们看到实参是a,b的地址,上面形参用指针接收,通过把a,b的地址传过去,解引用地址去修改原值。这也就是传址调用。 

6.函数的嵌套调用和链接访问

我们看上面的Swap函数示例,可以说就是一个函数的嵌套调用,在Test4中嵌套着Swap函数,

当然了,函数可以嵌套调用,但是不可以嵌套着定义。

而关于链式访问,让我们来看一段代码

void Test5()
{
	printf("%d", printf("%d", 43));
}

这个就是一段链式访问,把一个函数的返回值作为另一个函数的参数。

7.函数的声明与定义

在我们要完成一个程序,我们不会吧所以代码都写在一个.c文件中,因为这样写一是比较混乱,比较难修改,二是可读性也比较低,所以在项目中我们一般都是声明与定义分离的写法,把声明写到.h文件中,把定义写到.c文件中,这样写后我们就比较好维护,可读性也比较高。

在写函数时,我们都会把函数定义写在test函数上面,这样才能向上查找,如果把函数的定义写道test函数的后面,向上查找就会找不到,当然,我们只要把函数的声明放到test函数上面也可以。

我们可以看到 我们有两个.cpp文件 ,一个测试,一个定义,还有一个.h头文件用来声明

当然,在使用的时候.cpp,都要包含.h头文件。(在.h中我们可以把库函数的头文件都定义进去,.cpp在使用的时候,直接展开.h就可以把所有库函数头文件展开)

8.函数的递归

 函数的递归中心思想就是把一个大的问题,一层一层转化为一个小的问题去解决。

也就是 “大事化小”

当然,在执行递归的时候,也是需要必要条件的,如果不满足条件,可能就会发生不可预期的事情。

条件:

1.递归存在限制条件,满足了限制条件,递归就会停止

2.每一次递归都会接近这个限制条件

让我们看一组代码示例

int Test(int n)
{
	if (n == 1)
	{
		return 1;
	}
	return n * Test(n - 1);
}

int main()
{
	//求N的阶乘 ,思路:N的阶乘就是N-1的阶乘 乘以 N
	int n = 5;
	printf("%d ",Test(n));
}

 求N的阶乘,思路就是把求N的阶乘转化为求(N-1)*N的阶乘把大问题转化为小问题,当N=1的时候递归不再继续。

当然了,这次的递归只是初次讲解,作为一个重点,会专门开一个章节解析递归。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值