一、函数的概念
函数是C语言的的基本模块,通过对函数模块的基本调用可以实现相应的功能。函数相当于其他高级语言的子程序。
在计算机科学中,子程序是一个大型程序中的某部分代码,由一个或者多个语句组成,负责完成某个特定任务。
函数可以省去编写很多代码,减轻负担。函数也可以让程序更加模块化,提高代码的可读性。
说明:
1.一个C语言程序中仅有一个主函数main。
2.C语言程序中总是从main函数开始,调用完其他函数后总是会回到main函数,最后在main函数中结束整个程序。
3.一个C语言程序中可以包含多个头文件。
4.函数是以头文件开始进行编译的,而非函数。
5.所以函数都是相互独立且平行的,即一个函数只能调用其他函数,不能定义函数。
6.一个函数可以调用其他函数和其本身,但是不能调用main函数。
二、库函数
C语言的国际标准ANSIC规定了一些常用的函数标准,称为标准库。C语言本身并没有提供库函数,库函数是由不同编译厂商根据ANSIC规定的标准库给予了一些常用的函数,并进行统一,称为库函数。
2.1include命令的使用
调用库函数是必须在源程序中使用 include 命令。
#include<头文件> 或者 #include"头文件"
2.2库函数的网址
推荐几个库函数的学习和查看工具
CPlusplus.com
三、自定义函数
C语言中虽然给用户提供了大量的库函数供大家使用,但在很多情况下任然无法满足要求,需要用户自定义函数。
3.1函数的组成
类型标识符 函数名(形式参数表列)
{
声明部分;
语句部分;
}
换一种方式
ret_type fun_name(paral,*)
{
statement;
}
ret_type 返回类型;
fun_name 函数名;
paral 形式参数;
statement 语句;
void smile(void) { printf("hehe\n"); }
打印hehe。
#include<stdio.h> //计算n的阶乘 int mul(int n) { int i = 0; int sum = 1; for(i = 1; i<=n; i++) { sum = sum * i; } } int main(void) { int n = 0; //输入n的值 scanf("%d",&n); //进入函数 int sum = mul(n); printf("%d\n",sum); return o; }
计算n的阶乘。
3.2函数的参数
3.2.1实际参数
实际参数,简称实参,是真实传递给函数的参数。实参可以是常量、变量,表达式、函数等等,无论实参是哪种形式,在传给函数的时候必须是某个特定的值。
int main(void) { int i = 0; //实际参数 add1(1); add2(i); add3(7*i); }
3.2.2形式参数
形式参数,简称形参,是指函数名后面括号里的参数。形参只有在被函数调用时才会实体化,函数调用完后会自动销毁。
//形式参数 int add1(int num1){} void add2(int num2){} int add3(int num3){}
形参只有在被调用时才会分配空间,在调用结束后,会即刻释放所分配的内存单元,且形参只在其所在函数有用。
1.形参实体化后可以看作时实参的一份临时拷贝
2.形参和实参必须在数量、类型、顺序上严格一致,否则就会发生类型不匹配。
3.3函数的调用
在C语言中,函数调用的基本形式位
函数名(实际参数);
3.3.1传值调用
函数的形参和实参分别占有不同的内存块,且改变形参并不会影响实参的值。
#include<stdio.h> int add(int x) { int i = 10; return i + x; } int main(viod) { int i = 5; //创建变量num记录add()返回值。 int num = add(i); printf("%d\n",num);//num=15 return o }
3.3.2传址调用
传址调用,即将函数外部的参数以地址的方式传给另一个函数参数。传址调用可以将函数内部形式参数与调用它的形式参数建立起联系。
#include<stdio.h> //改变a的参数的函数 //内容涉及指针 void ret(int *pa) { *pa = 2; } int main(void) { int a = 0; //不返回值,改变a的参数 ret(&a); printf("%d\n",a);//a=2 return 0; }
四、函数的嵌套调用和链式访问
4.1函数的嵌套调用
当一个程序中存在多个函数,函数与函数之间是可以相互套用的。
#include<stdio.h> //第二次add int add2(int y) { int k = 30; return k+y; } //第一次add int add1(int x) { int j = 20; int num = add2(j); return x + num; } int main(void) { int i = 10; int sum = add1(i); printf("%d\n",sum);//sum=60 return 0; }
4.2函数的链式访问
函数的链式访问,即一个函数的返回值可以作为另一个函数的参数使用。
#include<stdio.h> int main(void) { //猜猜值为多少 printf("%d", printf("%d",printf("%d",50))); //5021 return 0; }
五、函数的声明和定义
5.1函数的定义
函数的定义,即函数的具体表现,实现函数功能的过程。
//函数的的定义 int add(int x) { return x + 1; }
5.2函数的声明
函数的声明一般放在头文件下面,以确保在调用函数时可以准确查找。
#include<stdio.h> //函数的声明 int add(int x); //主函数 int main(void) { int i = 10; int num = add(i); printf("%d\n",num); return 0; } //函数的定义 int add(int x) { return x + 1; }
在调用函数时,如果函数的定义不在调用函数所在函数的上方,就必须存在一个函数的声明放在调用函数所在函数的上方。
六、函数的递归
6.1函数递归概念
C语言中允许函数自己调用自己,这个过程的实现叫做函数递归。
优点:递归可以为部分编程问题提供最简单的解决方案。
缺点:递归算法会快速消耗计算机的内存资源。
int add(int i) { //没有递归结束标志 int j; add(j); return j; }
递归的核心思想是将大事化小。
6.2函数递归的条件
存在一个限制条件,当函数满足这个限制条件时,函数便不在递归。
每次递归结束后函数会越来越接近这个限制条件。
//计算n的阶乘 #include<stdio.h> //函数的声明 int mul(int n); int mian(void) { int n = 0; //输入n的值 scanf("%d",&n); //调用函数mul(); int sum = mul(n); printf("%d\n",sum); return 0; } //函数的定义 int mul(int n) { if(n!=0) return n*mul(n-1); else return 1; }
6.3递归和迭代
迭代,即循环,在程序中可以使用循环的地方一般都可以使用递归,相比较于循环,递归表现出其简洁性,但效率不高,而且结束递归也是需要考虑的重点。所以在考虑递归和迭代时也需要考虑一定情况。
#include<stdio.h> //使用函数的迭代求n的阶乘 //函数的声明 int mul(int n); int mian(void) { int n = 0; //输入n的值 scanf("%d",&n); //调用函数mul(); int sum = mul(n); printf("%d\n",sum); return 0; } //函数的定义 int mul(int n) { //函数的迭代 int i = 0; int sum = 1; for(i = 1; i<=n; i++) { sum = sum + i; } return sum; }
汉诺塔问题
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi Tower)的问题。大焚天在创造世界的时候做了三根金刚石柱子,在一跟柱子上从下往上按照大小顺序摞着64片黄金圆盘。大焚天命令婆罗门把圆盘从下面按大小顺序重新摆放在另一个柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问该如何操作?
代码实现
#include<stdio.h> void move(int x,int y) { ptintf("%c--->%c", x, y); } void hanoi() { if(n==1) move(a,c) else { hanoi(n-1,'A','C','B'); move(a,c); hanoi(n-1,'B','A','C'); } } int main(void) { int n = 0; scanf("%d",&n); hanoi(n,''A,'B','C'); return 0; }
青蛙跳台阶问题
有一只青蛙想要从台阶底部往上跳,但一次只可以跳一个台阶或者跳俩个台阶,问一共有多少种跳法?
代码实现
#include<stdio.h> int stage(int n) { if(n==1) return 1; else if(n==2) return 2; else if(n>2) return stage(n-1)+stage(n-2); } int main(void) { int n = 0; scanf("%d",&n); int sum = stage(n); printf("%d",sum); return 0; }