什么是函数?

这个大家自己思考吧(没必要去复制粘贴百度的定义到这里来。每个人有自己的理解,这个东西多用就会了)

函数(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;//返回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返回打印字符的个数
//最里面的printf 打印43 返回2
// 打印2 返回1
// 打印1 返回1
//最外面的 。。 。。。
}

点击并拖拽以移动

我们从最内层开始看起:

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);
}