函数——C语言的重要部分
函数
大纲:
函数是什么
在维基百科中对函数的定义:子程序
在计算机科学中,子程序,是一个大型程序中的某部分代码,由一个或多个语句块组成,它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
一般会有输入参数并由返回值,提供对过程的封装和细节的隐藏,这些代码通常被集成为软件库。
库函数
为什么会有库函数:
1.我们知道在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想把这个结果打印到屏幕上看看,这个时候我们会频繁的使用一个功能:将信息按照一定的格式打印到屏幕上(printf)
2.在编程的过程中我们会频繁的做一些字符串的拷贝工作(strcypy)。
3.在编程时我们也计算,总是会计算n的k次方这样的运算(pow)。
像上面我们描述的基础功能,它们是业务性的代码,我们在开发的过程中每个程序员都可能用得到,为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列的库函数,方便程序员进行软件开发。
具体怎么学习库函数呢?
cplusplus一个C++语言的的学习函数网站。
c++兼容c。
C语言官方网站:cpreference
cplusplus界面介绍
strcpyr函数为例
char是函数名,strcy是参数,后面括号里面的是返回类型
这里是指把源头指针指向的字符串转移到目标指地址。
copy string 是函数功能的介绍
parameter 是形式参数。
Return Value 是返回值的介绍
Output 是指这个函数最后输出的结果是什么
See also 则是指和这个函数相关的其他函数
现在,我们学习几个函数:
strcpy 字符串赋值函数
我们要把arr2传到arr1里面去
于是,arr2就是源头,arr1就是目标地址。
当出现某函数未定义的错误时大概率就是头文件没有包含
这样就是代码正常运行
strcpy可以把目标变量中的\0一同拷贝
接下来学习 memset 语言初始化函数
这段代码就是将arr数组中的前5个字符替换成 x
上面两个函数的头文件都是 #include<string.h>
学会使用库函数
练习: 写出函数找出两个整数中的最大值。
就是这段代码
写出一个函数可以交换两个整型变量的内容
这是代码及运行结果
但是却没有交换
因为 当函数调用的时候,实参(a,b)传给形参(x,y),形参是实参的一份临时拷贝。所以对形参的修改是不影响实参的
解决方法是 传送 a b 的地址
这叫传址调用,上面不能实现的叫做传值调用
函数的参数
这里的实参可以是常量,变量,及表达式和函数。
必须得有确切的值
函数的调用
传值调用与传址调用
写出一个函数可以交换两个整型变量的内容
这是代码及运行结果
但是却没有交换
因为 当函数调用的时候,实参(a,b)传给形参(x,y),形参是实参的一份临时拷贝。所以对形参的修改是不影响实参的
解决方法是 传送 a b 的地址
这叫传址调用,上面不能实现的叫做传值调用
练习:
(1)打印100~200之间的素数
这个是代码
这里的sqrt函数是计算数字的平方根,使用时需要加上头文件#include
(2)打印1000~2000之间的闰年
(3)写出一个函数,实现一个整型有序数组的二分查找
二分查找/折半查找
在一个有序数组中查找具体的某个数字n。
先将最左边的数字标记为left,最右边的标记为right,再将两者相加除2所得值mid相比较,如果较大,mid则变为left,right则为原来的right。较小则相反。
假设n = 7,首先left下标为0right下标为9,mid则为4,4
mid还可以这样写
所以这道题可以写成这样
结果是
但这里计算数组大小时计算的是错误的
这里其实传送的只是首元素的地址
这个地方的arr本质不是一个数组而是一个指针
这个是修改正确后的代码
其实形参写成数组也可以
(4)写一个函数,每调用一次这个函数,就会将num的值增加1
viod函数
void函数与其他函数的区别,viod函数不需要返回值,而其他函数需要
注意:
函数,如果不写返回值,函数默认会返回一个值,有些编译器上返回的是:最后一条指令产品的结果
函数的嵌套调用和链式访问
嵌套调用
main函数调用three_line,three_line调用new_line
链式访问
把一个函数的返回值作为另一个函数的参数
这里的字符串长度是6,strlen的返回值6就作为了printf函数的参数,所以结果就是6
看下面这个代码
我们可以通过查询cplusplus得,printf函数的返回值是打印在屏幕上字符的个数。
最里面的printf函数打印的是43,他的返回值就被中间的printf打印,结果是2,再然后中间的函数的返回值又被最外面的打印,结果是1。所以最终结果是43 2 1
函数的声明和定义
当我们的代码是这样时运行会报错说Add未定义
这是因为编译器扫描时是从上往下扫描,而扫到Add时发现没有见过Add,这时的解决办法是要么将Add写在前面,要么就是在前面声明一下Add函数(只要在Add函数使用之前就可以)
这就是函数声明
高级的函数调用
当我们需要多个人合力写项目时,就需要用到较为高级的函数调用
我们首先写一个主函数
我们再新建一个源文件写出我们即将调用的函数
我们再在主函数头部写出要调用的函数
然后再运行
一般我们在头文件中放函数的声明,类型的定义,头文件的包含
在源文件放函数的定义
这样写的好处是我们可以按模块写
还可以把函数的实现的代码隐藏起来
如何出售的代码
假如我我是张三通过业余时间写了一个游戏引擎,想卖它挣钱。
我们要实现的效果是:我可以给您用,但你不知道我是怎么写的
假设这是张三创建的游戏引擎
李四则对这个游戏引擎比较感兴趣,想买
但张三又不想让李四看见
张三则就要右击鼠标点击属性
在配置属性的常规选项下将配置类型改为静态库
点应用,确定
这时我们再按Ctrl+F5时会发现无法运行
但它也已经生成了一个add.lib文件
这个.lib文件就是张三游戏引擎所对应的静态库文件
被李四买走就可以用了,李四买完后放在他项目的debug文件夹里
但李四打开.lib文件发现都是些乱码,根本看不懂
上面其实是一些二进制信息,里面包含了很有价值的东西
张三随后再把头文件给李四
李四把.h文件加到工程里面后,发现还是无法编译
报错是无法解析的外部符号Add
这里要想使用就要加载一下静态库
以后我们要卖代码时只需要将运行的.lib文件和.h文件卖出即可
这就更加说明了以后写代码要规范一些
对于这里的头文件包含,编译器在处理的时候就会把头文件的内容直接拷贝到.c文件里