目录
1.函数
2.库函数
2.1概念
2.2使用方法
3. 自定义函数
3.1 概念
3.2 基本格式
3.3 实参和形参
3.3.1 实参(实际参数)
3.3.2 形参(形式参数)
4.return 语句
① return 可以返回一个数值,也可以返回表达式
②return 后面可以什么也没有
③return 函数返回类型和函数定义时写的返回值类型不一样的时候,会被强制转换为第一行定义时的返回类型。
④return 后面的语句不会被执行
5.数组做参数
6.函数的嵌套调用与链式访问
6.1嵌套调用
注意:可以嵌套调用,但是不能嵌套定义
6.2 链式访问
7.函数的定义与声明
7.1 定义
7.2 声明
8.模块化编程——将程序拆分为多个文件
在C语言中,函数是实现一定功能的代码块。一个完整的C语言程序,我们可以认为就是由一个个的函数组成的。为什么要引入函数呢,因为在C语言的程序当中,有些功能我们会频繁的使用,比如输入输出,而如果每次我们使用的时候都需要重新写代码来实现,会大大的降低开发的效率,同时还会增加出错的概率。因此我们需要引入函数。
而在C语言中函数主要有两种:库函数和自定义函数。
库函数全称是C语言标准库函数,指的是:由C语言标准规定的一些实现特定功能的常用函数。正如我们刚才说的,在C语言中有一些功能经常使用,因此C语言标准规定了一些函数比如printf,然后明确了他的功能,使用方法,但是并不负责功能的实现。编译器根据C语言标准库的规定来写代码实现这些功能,程序员只需要根据语法规则,调用这些函数即可。
在使用库函数的时候,首先我们需要了解他的功能, 参数,返回类型等信息。
同时注意包含对应的头文件
虽然c语言函数库已经给我们提供了很多函数,但是远远不够,面对复杂的功能,我们也同样难以应对。因此我们需要引入自定义函数,自定义函数指的是由用户自己设计编写的函数。
自定义函数的基本格式是:
我们来分析一下函数的功能,函数我们可以理解成一个工厂,我们知道工厂实现的功能是:我们给它输入原材料,经过工厂一系列的加工处理以后返回给我们产品,类似的:函数名就相当于是工厂的名字,我们在调用函数的时候需要写函数名,而参数就是原材料,函数体就是工厂的一系列加工处理。而返回值类型就是加工出产品的类型。
请看加法函数的例子:
输入两个整数,返回两个数的和
这样写当然没问题,但是我们也可以将加法部分写成Add 函数来完成:
我们来分析一下这个代码:
实参是函数调用时传递给函数的具体数值或表达式。
实参提供了函数在执行时所需要的具体数据。
实参的值被传递给对应位置的形参。
形参是函数定义中用于接收参数值的变量。
形参位于函数的参数列表中,用于声明函数期望接收的数据类型和参数个数。
形参在函数体内的作用范围是局部的,它们只在函数执行期间有效。
同时如果我们只是定义了函数,但是我们并不调用函数的话,函数的参数其实是形式上存在的,并不会向内存申请空间,不会真实的存在。只有当我们调用函数的时候,才会向内存申请存储空间,这个过程称为形参的实例化。
因此,在调用的时候使用的参数是实际参数,即实参;在函数定义的时候使用的参数是形式参数,即形参。
形参可以看作是实参的临时拷贝。这个我们可以通过观察他们的地址得知。
通过调试中的监视,我们可以发现,虽然x的值和a的值一样,但是位置是不一样的,b和y同理,因此时你可以发现,他们其实是两种东西。
如果是表达式,返回的是表达式的值。比如:
这种适用于没有返回值的情况,比如打印
写一个代码,将原来数组里面的元素全部变为0。
当然我们可以这样写:
运行
如果我们将数组内容转变成0的过程转变成Set_arr 函数,我们也可以这么写:
当数组为参数的时候有一些注意事项
1、形参的变量名可以跟实参一样的。
2、在参数是数组的情况,形参数组和实参数组是同一个数,用监视窗口观察一下。
函数的嵌套调用是指在一个函数内部调用另一个函数。
比如我们写个代码判断用户输入的某年某月是多少天。
分析问题,首先我们知道除了2月份以外,其他的月份每年都是固定的天数。
而针对2月份需要判断是否为闰年,如果是的,28+1,不是还是28。
运行一下:
这样是不可以的!
链式访问指的是,讲一个函数的返回值当成另一个函数的参数来使用。
我们举个例子
首先我们要明白程序的执行顺序,由里到外
第一个printf先执行,打印43,然后第二个函数执行,打印的是第一个函数执行以后的返回值,那么printf的返回值是什么呢
返回的是输出字符的个数
因此我们可以想到程序的结果是43(第一个printf的输出值)2(43是两个字符)1(2是1个字符)
在编程中,函数的定义是指明函数的实际实现(具体的代码)的过程。函数的定义包括函数的名称、返回类型、参数列表和函数体。
比如我们最开始写的Add函数
在学习函数声明之前,我们想一个问题,我们之前写的代码,函数的定义都是在主函数之前,如果在主函数之后呢,我们观察一下会出现什么情况。
这个时候,我们可以发现,程序出现了警告,那是因为程序是由上往下执行的,当看到Add函数的时候,不认识,所以出了警告,因此,我们如果把函数的定义写到了后面,我们需要在前面写点什么,让程序知道后面有这个函数,此时就需要声明:
函数的声明是指在程序中提供有关函数的信息,而不提供具体的函数实现。声明包括函数的返回类型、函数名称和参数列表。函数的声明告诉编译器在程序的其他地方会有一个具有特定特征的函数,使得编译器能够正确检查函数的调用和使用。
那为什么放在前面并没有声明也没有报警告呢,因为定义本身就是一种特殊的声明。
从我们刚开始学习,我们一直将代码写在一个文件中,这样对我们来说可能比较简单,但是这并不是长久之计,因为在以后我们做的主要是大型的项目,一个项目不可能只由一个人来编写,如果都写在一个文件里,就不能同时工作,效率很慢。
因此我们可以使用模块化编程,模块化编程的好处有:
可维护性: 每个模块专注于特定的任务,因此修改或扩展功能时,只需关注与该模块相关的部分。
可读性: 模块化设计使得代码更易读。每个模块都有自己的目的和接口,开发者可以更容易理解和浏览与当前任务相关的代码。
重用性: 模块可以在多个项目中重复使用,提高了代码的重用性。这尤其有助于构建库和工具,可以在不同的上下文中使用。
团队协作: 不同的团队成员可以同时工作在不同的模块上,减少了彼此之间的冲突。每个模块都有清晰的接口,团队成员可以更容易地协同工作。
测试: 模块化设计有助于更容易进行单元测试。每个模块都可以独立测试,确保其功能的正确性。
那我们该如何进行模块化编程呢,操作方法是什么样的呢?
一般情况下,我们将函数的声明放在头文件中,函数的实现放在.c文件
添加头文件,以add 函数为例
这样我们就可以将一个程序分成三个文件
如果另一个程序想用,只需添加add.h 和add.c 即可。
注意:别忘了包含头文件
自己写的用双引号。
运行:
没问题!