1. 重新认识函数
在数学中我们接触函数,研究函数,创造函数。与此同时,C语言中也存在着函数。
数学中我们一开始学习的是单变量函数,但随着学习的深入,出现了多变量也就是多元函数。而在C语言中,我们也有着有多元函数。
数学中的函数和C语言中的函数都有着一个输出值(数学中多为y or z,C语言中称其为返回值)
由此,我们可以在宏观上对函数有这样一个逻辑上的理解
在英文中,函数被叫做“function”,同时也有着功能的意思。正如其名,C语言中函数的出现就是为了实现某一功能。
2. C语言中的函数
2.1函数的结构
先来看一段代码
int test(int x,int y)
{
//the body of this function
return 0;
}
int main()
{
test(1,2);
return 0;
}
首先我们要知道的是这个函数名为test函数。
test后边的括号是该函数的形式参数列表,通常我们设置这些形式参数就是为了接受来自主函数的值,并且对其做一些处理,最后得到输出。
在大括号内部便是该函数的主体部分了,里面可以有各种语句,对数值的处理,循环选择判断等等等等。
最后一行的return 0;称为返回值部分,程序一旦读到这句话就会立刻结束该函数并且将其后边表达式的结果作为返回值,返回给调用这个函数的地方。返回值的值属性是return后边表达式的结果,而它的类型属性是函数的类型,即函数名前面的类型(在未声明的情况下为int)
注意:一个函数只能有一个返回值!
2.2 函数的调用
要调用我们自己写的函数时,只需要在函数名后加一个括号,并在括号内填入类型相对应的变量或者常量。这时,这个括号被叫做函数调用操作符。如上代码所示。倘若要接收该函数返回的值时,也只需要声明一个与该函数返回类型相同的变量进行接受,如下所示:
int ret = test(1,2);//函数返回类型为int
补充:函数不能嵌套定义,但可嵌套调用。
2.3 形参,实参,传值,传址
先看这样一个代码,看看swap函数到底有没有成功swap。
#include <stdio.h>
void swap(int x, int y)
{
y = x ^ y;
x = x ^ y;
y = x ^ y;//这边起到交换x y值的作用
}
int main()
{
int x = 2;
int y = 1;
printf("%d %d\n", x, y);
swap(x, y);
printf("%d %d\n", x, y);
return 0;
}
结果:
没有成功交换,为什么呢?
其实这就是典型的传值调用,我们只是把值传入了这个函数,但是这个值的来源,即主函数中的xy并不会受到影响。而swap内的xy在函数结束的时候就被销毁了,所以根本不会对主函数内部xy造成影响。
接下来就是一个有用的swap函数
#include <stdio.h>
void swap(int *x, int *y)
{
*y = (*x) ^ (*y);
*x = (*x) ^ (*y);
*y = (*x) ^ (*y);//这边起到交换x y值的作用
}
int main()
{
int x = 2;
int y = 1;
printf("%d %d\n", x, y);
swap(&x, &y);
printf("%d %d\n", x, y);
return 0;
}
结果:
而这边则是把主函数中的xy的地址传递给了swap函数,int *x 和 int *y内存着主函数内xy的地址,解引用后直接找到xy并且对其进行换值操作。
2.4 递归函数
递归函数在概念上十分简单,就是在创建函数的时候又用到自身函数(即该函数自己调用自己)
下面看一个递归函数的例子
先了解一下斐波那契数列,它的每一项(除去第一二项外,其他项都是由前两项之和得来的数)。
函数功能:求斐波那契数列的第n项的值
int Fib(int n)
{
if (1 == n)
{
return 1;
}
else if (2 == n)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
可见,该函数在其函数体内调用了其自身,下面将以图解的方式演示Fib(4)的运算过程
递归函数有着将大事化小的思想:要求Fib(4)? 那就先求Fib(3) 然后Fib(2) 然后Fib(1) 最后等到满足返回条件了,就开始逐级将值返回。
可见,递归函数有着代码量小的优点,可用很少的代码完成大量的操作。但同时,如果递归函数使用不当或者内部结构不合理,容易造成栈溢出的问题(stackoverflow),导致程序异常终止。
2.5 C语言库函数
在C语言中,很多函数其实是现成的,不需要我们去构建,比如说我们经常使用的scanf 还有 printf 它们都是被包含于头文件<stdio.h>内的,要使用库函数时,我们只需要用#include调用其头文件,然后就可以直接在程序中使用该函数了。使用函数时需注意其返回值,形参类型。