前言
今天我们来学习一波函数的概念,帮助各位理解函数,本次博客取自一些书籍以及各大网站的讲解,把它整合在一起并且详细讲解
1函数的理解
我们得知道什么是函数,函数的作用是什么,好不会表述没关系,我们翻书
c primer plus 是这么说的"函数是指完成任务的独立程序代码单元"
函数的分类1 库函数 2 自定义函数
库函数分很多种 IO函数 字符串操作函数 内存操作函数
时间/日期函数
数学函数(要用#include<math.h>) 其他函数
函数在c语言的专业名词为fuction
2自定义函数的语法
函数有什么呢
举个最简单的例子,看代码
//1函数的声明
int Add(int a,int b);
int main()
{
int a=10;
int b=20;
printf("%d",Add(a,b));//2函数的调用
return 0;
}
3函数的定义
int Add(int a,int b)//4有返回值的函数 返回类型为int
{
return a+b;
}
1函数的声明
函数的声明可以使编译器找到该函数,如果说自定义函数在main的后面并且没有声明,那么就会出现错误
举例吧
当只有一个自定义函数时,编译器并没有报错,但是是有警告的
>D:\c\haha\FileName.c(963,15): warning C4013: “Add”未定义;假设外部返回 int
其实在语法中这个是错误的,只不过编译器优化了
那么接着看 当我们调用两个自定义函数时
就会发生报错,解决方法很简单的
只要提前声明不就好了,让我们的编译器知道有这么一个函数不就好了
相信大家大家已经会解决这类问题了
2函数的定义
哎呀函数的定义不就是 函数的内容吗 {}就是花括号里头的内容,
当然我们发现在函数的声明中有两个参数 在定义的过程中
语法为 返回类型 函数名(类型 +变量名1,类型+变量名2````````)
我们从左往右看
返回类型分两个 一个是有返回值 通常的表述为类型 比如 int float double int*等等
另一个是无返回值 就直接是void 他们会返回一个值表示某些特殊的条件
大家也看到上面的代码中出现了
函数名就是他的名字 在C语言中函数名不可以重复,既自定义的函数不能与库函数同名
并且自己也不能写两个同名函数,在c++中是可以的,叫做函数重载,以后会提到
接着是参数,在函数声明中的参数叫做形参,而在调用中的参数叫做实参
3函数的调用
在函数的调用中就用讲头了, 1在函数的声明中有几个参数,我们在调用时就必须要使用
几个参数 2参数的类型必须一一对应不能乱传 3在调用时,函数的实参会被拷贝一份到形参中
但是形参的改变不会影响到实参
我们可以举例,还是用最简单的例子吧 交换 a b变量的值
void Swap(int a,int b)
{
int temp=a;
a=b;
b=temp;
}
int main()
{
int a=10;
int b=20;
Swap(a,b);
printf("%d %d",a,b);
return 0;
}
此时 a b的值并没有改变
解决方法也很简单
void Swap(int *a,int *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int a=10;
int b=20;
Swap(&a,&b);
printf("%d %d",a,b);
return 0;
}
只需通过指针即可
其实这两种调用分别称为 传值调用和传址调用
3库函数
库函数顾名思义,就是在C语言库里的函数,他们已经被定义声明好了
我们只需拿来就用就好,为了方便大家理解
我们还是举例子说明
stdio库函数 printf scanf io输入输出函数举例
#include<stdio.h>
int main()
{
int a;
scanf("%d",&a);
printf("%d",a);
return 0;
}
strlen 库函数 全名string(字符) length(长度)所以该函数时计算字符串的长度 举例
#include<stdio.h>
#include<string.h>
int main()
{
char arr[]="hahahaha";
int a = strlen(arr);
printf("%d", a);
return 0;
}
这个函数是计算字符串长度的函数(不包括\0)
math库函数 举个例子 floor sqrt
#include<stdio.h>
#include<math.h>
int main()
{
int a=10;
int b=floor(sqrt(10));
printf("%d",b);
return 0;
}
floor(a)返回一个不超过a的最大整数
sqrt(a)计算a的算术平方根
我们这里以三个最常用的库函数给大家举例
4函数的嵌套使用和链式访问
1嵌套使用
函数的内部可以再调用函数
举例
#include<stdio.h>
int main()
{
printf("%d",10);
return 0;
}
没想到吧这就是在主函数里调用库函数printf,可以说是最简单的例子了
2链式访问
把一个函数的返回值作为另一个函数的参数
看代码
提示printf函数的返回值为size_t类型 大小为打印的数量
#include<stdio.h>
int main()
{
printf("%d",printf("%d",printf("%d",43)));
return 0;
}
大家看的出结果吗答案是4321
43是两个占位符第一个内部的printf返回2,接着把2打印出来
又返回1,再把1打印出来
5函数递归
运用自身的编程技巧称为递归(recursion)
把大型问题转化为小型问题
举例来看 看一看最简单的递归
void print();
void print()//结果是一直打印haha
{
printf("haha");
print();
}
int main()
{
print();
return 0;
}
//这就是最简单的递归函数,但此函数:如递归所有控件路径,函数将导致运行时堆栈溢出(stack overflow)
接下里再看代码
1.接受一个整形(无符号),按照顺序打印它的每一位
void NB(int x);
void NB(int x)
{
if (x > 9)
{
NB(x/10);
}
printf("%d\n", x % 10);
}
int main()
{
int n;
scanf("%d", &n);
NB(n);
return 0;
}
看结果
说实话,如果不理解递归可以画图来理解
我们以上述代码结果例子来举例吧
1 接受一个值 123456
2进入函数 NB() 123456>9 执行NB(123456/10)12打印(123456%10)结束该函数
3第一次递归 12345>9 执行NB(1234) 11打印(12345%10)返回到原有的函数
4第二次递归1234>9 执行NB(123) 10打印(1234%10)返回到第一次递归
5第三次递归123>9 执行NB(12); 9打印(123%10)返回到第二次递归
6第四次递归12>9 执行NB(1) 8打印(12%10)返回到第三次递归
7第五次递归1<9 打印(1 %10)返回到第四次递归来
上面就是递归的全过程了
通过这个我们可以总结出两点
1.递归要有限制条件
2.每次递归要更接近条件
总结
今天的内容就到这里了,之后还是要多加练习,祝大家天天开心
上一张思维导图