什么是函数?
这个大家自己思考吧(没必要去复制粘贴百度的定义到这里来。每个人有自己的理解,这个东西多用就会了)
函数(function) 通过实参(argument)初始 形参(parameter) 执行完函数体(function body) 返回(return value)一个值。(或者不返回)
函数类型
1.库函数
提供给大家一个学习库函数的网站:http://www.cplusplus.com/reference/
2.自定义函数
比如我们常用的
int main(){
}
1.这个 int 就是返回值的类型 我们一般在main函数最后一行加 return 0
2.main 是函数名 可以自己起
3.()括号内 可以放形式参数 也可以不写
4.大括号内就是函数体 写函数的功能 定义函数
强调一下函数的声明与定义不一样!
声明就像你在main函数开头初始化变量 它的作用就是让main函数顺序执行到调用语句时知道这个你在前面说过,不至于让main函数很懵逼 只用写上面的1,2,3
如:int Max(int a, int b);
定义就需要具体实现这个函数的功能 1,2,3,4都需要写完
int Max (int a,int b) { return (a>b)?a:b; }
形参与实参
这个不同大家自己百度就行。
自己可以在vs里调试看看你设置的形参与实参的地址(形参与实参地址时不一样的)
嵌套调用
可以类比数学的复合函数f(g(x))
#include <stdio.h> #include <math.h> #define e 2.7 float g (int x) { return pow (e,x); } float f (int x) { return 2 *g(x)-1 ; } int main () { int x = 0 ; printf ("计算2*e^x-1\n请输入 x:\n" ); scanf ("%d" ,&x); printf ("f(%d) = %.2f" ,x,f(x)); }
链式访问
例1:
#include <stdio.h> #include <string.h> int main () { char arr[20 ] = "hello " ; int ret = strlen (strcat (arr, "world" )); printf ("%d\n" , ret); return 0 ; }
arr数组在经过strcat后变成了"hello world"
我们知道strlen读取的长度是11(不懂为什么可以按照我给的网站去查strlen ,strcat的用法,里面说的很到位)
例2:
#include <stdio.h> int Max (int a,int b) { return (a>b)?a:b; } int main () { int max = 0 ; max = Max(Max(7 ,Max(1 ,2 )),6 ); printf ("%d" ,max); }
最后输出是7(其实直接看谁最大就好了,不知道原理也没事)
例3:
#include <stdio.h> int main () { printf ("%d" ,printf ("%d" ,printf ("%d" ,printf ("%d" ,43 )))); }
我们从最内层开始看起:
printf(“%d,43”)它会输出 43
printf函数会返回它打印的字符数 所以它返回 2
我们看下一层:
printf(“%d”,2);
这时打印 2 返回 1
继续下一层:
printf(“%d”,1);
打印 1 返回 1
同理最外层会打印1
所以最总结果是:43211
总结一下:链式访问需要关注函数的返回值
递归
什么是递归?
程序调用自身的编程技巧称为递归( recursion)
递归的两个必要条件
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2.每次递归调用之后越来越接近这个限制条件
举个例子:
求第 n 个斐波那契数列
先用数组法
以我的经验 普通的做法往往能给递归法找到规律
#include <stdio.h> int main () { int arr[50 ] = {0 }; int i = 0 ; int n = 0 ; arr[0 ] = 1 ; arr[1 ] = 1 ; printf ("你想知道斐波那契而数列的第几个数:\n" ); scanf ("%d" ,&n); if (n==1 || n==2 ) printf ("第 %d 个斐波那锲数列是 %d" ,n,1 ); else { for (i = 2 ; i<n; i++){ arr[i] = arr[i-1 ] + arr[i-2 ]; } printf ("第 %d 个斐波那锲数列是 %d" ,n,arr[i-1 ]); } }
递归法:
#include <stdio.h> int Fibonacci (int n) { if (n==1 || n==2 ) return 1 ; else return (Fibonacci(n-1 )+Fibonacci(n-2 )); } int main () { int n = 0 ; printf ("你想知道斐波那契数列的第几个:\n" ); scanf ("%d" ,&n); printf ("%d" ,Fibonacci(n)); return 0 ; }
但是递归法做有的问题并不聪明==(比如这个问题)
因为如果给的n很大它会重复计算很多次,不断调用意味着更大的空间。可能造成栈溢出(stack overflow)
所以下面这个做法也许是解决这一类问题的好做法
迭代法:
#include <stdio.h> int main () { int Fir = 1 ; int Sec = 1 ; int Thi = 1 ; int N = 0 ; printf ("请输入你想知道第几个斐波那契数列:\n" ); scanf ("%d" ,&N); while (N>2 ){ Thi = Fir + Sec; Fir = Sec; Sec = Thi; N--; } printf ("%d" ,Thi); }