目录
前言
一、函数是什么?
二、函数的定义
1.有参函数和无参函数的定义示例
有参函数的定义示例:
三:函数的参数
四:函数的调用
五:函数的声明
六:函数的嵌套调用
在编写一个大型程序时,我们如果把所有内容都放在主函数之中,就会使主函数变得庞杂,头绪不清,使程序员在检查和维护时摸不着头脑,大大增加了程序员的操作难度。但如果我们按照函数执行的功能分门别类的编写一些子函数,让每一个子函数都执行特定的功能,就能让程序条理更加清楚,既方便自己编写程序,也方便其他程序员观看,这就是模块化程序设计的思路。
下面是维基百科对函数的解释:子程序
在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组 成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性。
一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。
无参函数的定义:
类型名 函数名()
{
函数体
}
在我们定义一个函数时,我们需定义其类型,名称,参数。其中无参函数不需要参数其函数名称后的括号中不需填或者用void表示空的意思。因为无参函数没有参量,则它无法接收主函数转输的数值,则主函数在调用无参函数时,无法对无参函数内部进行操作,因此一般情况下,无参函数用来执行特定的一组操作。
函数的返回值:主函数通过实参向函数传递数据,让函数执行特定的功能对数据进行处理,函数调用后会给主函数一个反馈,我们一般用return(后接函数想要转递给主函数的数据),当然有的函数没有返回值。
在调用有参函数时,主调函数和被调用函数之间有数据传递关系。我们把在定义函数时函数名称后面括号中的参量称为"形式参数",简称为形参。在主函数中调用函数时,函数名称后括号里的参数成为“实际参数”,简称为实参。
真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。无论实参是何种类 型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。
形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配 内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在 函数中有效。
现在我们用一个例子来简单解释形参和实参之间的关系:
#include<stdio.h> void exchange(int x, int y)//这是一个实现两个数字交换的函数 { int n=0; n = x; x=y; y = n; } int main() { int a = 10; int b = 20; printf("交换前:%d %d\n", a, b); exchange(a, b);//这是函数调用的方式之一:传值调用 printf("交换后:%d %d\n", a, b); return 0; }
在这个函数中,函数体中实现的功能是两个数的调换,但我们看一下结果如下:
现在我来解释一下原因,在调用这个函数时确实把a的值传递给x,b的值传递给y,通过调试不难发现在函数中确实对下x和y进行了交换,但这个交换为什么没有对实参a和b产生影响?这是因为我们在调用函数时内存会为形参分配一个临时的内存单元,而这个内存单元和实参的内存单元的地址不是一样的,在形参进行交换后,由于形参并没有实参的地址,所以无法把数据传回实参。
所以我们通常说:形参实例化之后其实相当于实参的一份临时拷贝,但由于形参不知道实参的地址,所以形参的改变不会影响到实参。但我们可以通过传址调用,把实参的地址传递给形参,这样形参数据改变后可以凭借着地址把改变后的数据拷贝回来。
示例如下:
#include<stdio.h> void exchange(int* x, int* y) { int n = 0; n = *x; *x = *y; *y = n; } int main() { int a = 10; int b = 20; printf("交换前:%d %d\n", a, b); exchange(&a, &b); printf("交换后:%d %d\n", a, b); return 0; }
结果如下:
果然,通过传址调用我们成功的实现了两个数交换函数的实现。
通过上述的例子我们知道了函数调用的两种方式传值调用和传址调用。
传值调用
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。
传址调用
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起正真的联系,也就是函数内部可以直接操 作函数外部的变量。
主函数调用函数的方式一般是
int ret=max(a,b);
函数名称 (实参)
在函数有返回值时,一般会定义一个变量来储存返回值,但要注意一般该变量的类型要与函数返回值的类型和函数的类型保持一致,在特殊情况下可以通过强制类型转换来保持一致。
函数必须先声明后使用
1:如果使用库函数,应该在本文件的开头用#include指令将调用有关库函数时所需用到的信息包含到头文件中来。
2:在自定义函数时,由于程序是从主函数开始运行的,到主函数结束时结束,如果主函数在被调用的函数之前则必须在主函数中对被调用的函数进行声明,告诉计算机有这个函数,否则该函数不会执行。
所有函数都是平行的,即在定义函数时是分别进行的,是相互独立的。一个函数不从属于另一个函数,即函数不能嵌套定义,即不能在函数中定义函数。但函数可以嵌套使用,即在一个函数中调用另一个函数,但是main函数是不能被其他函数所调用的。main函数是被系统操作调用的。