c语言基础知识梳理——函数

本文深入探讨C++函数的基础知识,包括函数的定义与声明、库函数与自定义函数的使用、传值与传址的区别,以及递归的概念和应用。通过实例解析,帮助读者理解函数在编程中的重要作用,同时提醒在使用递归时需要注意的效率问题。
摘要由CSDN通过智能技术生成

今天来总结一下函数的相关基础知识点,希望对各位能有所帮助,也借此完善一下自己的知识库。博主刚写博客,水平有限,望各位海涵。

目录

                  函数的定义和声明

函数的分类

函数传参

递归


函数的定义和声明

什么是函数的定义和声明呢?这是我们应该首先要去理解的问题。

函数的定义:简单来说就是说明函数是如何实现的。

函数的声明:具体就是告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。

注意事项:1.函数的定义可以放在使用后,而函数的声明必须放在使用前 

                  2.先定义可以不用声明,后定义需要先声明     

                

函数的分类

总体来说分为库函数自定义函数

1.为什么要有库函数呢?库函数是前人把一些常用的函数总结打包好了,不用我们每次编程时都要重复敲一段代码去实现一个常用函数,节省了时间。常见的库函数有scanf,printf,getchar......,使用库函数之前记得引用头文件,编译器才不会报错。常用的库函数学习网站有MSDN,Cplusplus,英文不好的可以用翻译软件阅读一下,相关介绍十分详细。

2.自定义函数则可以实现任何功能,如果我们能力够的话。虽然自定义函数的功能很多,但有很多注意事项,因为从函数的参数类型(包括实参和形参),返回类型,函数的定义声明都要自己实现。下图由一个基础的加法函数为例,看看函数是如何进行定义的

 此处应该注意,z变量是在函数内被定义的,所以等函数调用完后,z变量就会被销毁,相当于一次性用品。

那我们接下来看看一整套自定义函数的使用流程

 这是一个返回最大值的函数,返回类型为int,所以用一个max变量接收最大值,然后进行打印。

这里要注意的应该是a,b和x,y的关系。

a,b是实参,就是你要传进函数的参数。而x,y为形参。

我想让a,b进行比较得到最大值,所以在调用符号——()里写a,b。然后由x接受a的值,y接受b的值,这里的x相当于a,y相当于b。这就是传参的过程,具体传参稍后再讲。

注意事项:实参必须有确定的值,以便把这些值传送给形参;形参实例化之后其实相当于实参的一份临时拷贝,会开辟相应空间。

函数的传参

传参具体分为传值和传址。接下来由两段代码来展示何为传值和传址。

这是之前的得到最大值函数,为传值 

 

 这是交换两个整形内容的函数,为传址。

传址就是传的地址,所以形参接受地址时就理所应该要有指针去接收,具体是什么类型的指针呢,就要看实参的类型了。

   读到这里可能道理都懂了,但往深了想,为什么有传参和传址的区别呢,统一一个传参方法不是更加方便吗?

首先通过上面两个代码,我们不难发现传值调用对形参的修改不会影响实参。而传址调用对形参的修改会影响实参。所以当我们设计函数进行传参时要明确是否要改变实参

其次我们应该大概了解一下在调用函数的时候,都会在栈区开辟一块空间(还没学栈区的可以理解为在电脑内存里开辟一块空间),栈区存放局部变量和函数形参。而形参又是实参的一份临时拷贝,所以如果实参为一个很大的数组,所占内存很大,又传给形参,那么栈区被占的空间很多,空间利用率就较低了。而传址调用不管实参的内存多大,传的都是一个地址,形参都为指针,大小为4或8个字节,也不用开辟新的空间,也省了时间。

总体来说,就是以下两点

  • 传值调用对形参的修改不会影响实参。
  • 传址调用可以通过地址改变实参,不会开辟新的空间,省内存

递归

简单来说就是将一个大的事件分为很多个小的且重复的动作,不断调用函数本身去实现小且重复的动作,从而将一个大且复杂的事情简单化。

使用条件:1.存在限制条件,不能死循环,否则会栈溢出

                  2.每次调用函数后,都会越来越接近这个限制条件

例子:求字符串的长度

 如果不是‘\0’,返回1+get_len(arr+1)

arr+1其实实现了让地址循环往后走一位,如果&(arr+1)再不为'\0',再返回1+get_len(arr+1)。此时第一行的结果其实就是2+get_len(arr+2)。

以此类推直到遇到'\0'。

例子:求斐波那契数

本质上为下图

 

 

当求得的数字较大时,使用递归的方法计算机所要计算的量是相当大的,因为每次计算一个第n项时都需要计算第n-1项和第n-2项 

我们通过求解第40项来观察fib(3)的计算次数来观察

 由此可知计算量巨大,越到后面效率越低。

因此此处应该使用迭代求法更优——通过对a,b的反复赋值进行求解

 由此可得迭代的效率更高

为什么有时候用递归简便,而有时候用迭代简便呢?

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

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

3.有时迭代实现比递归实现效率更高,但可读性差些。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值