C语言复习巩固(四) 函数

什么是函数?

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

函数(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);
}

----------本篇结尾----------

谢谢观看,有什么问题请指出!

更多代码练习请关注本人的GitHubhttps://github.com/hairrrrr/ccode

对您有帮助请点一个赞 或者关注我!

发布了19 篇原创文章 · 获赞 88 · 访问量 3335

猜你喜欢

转载自blog.csdn.net/qq_44954010/article/details/103687073