目录
一.什么是函数
二.函数的分类
1.库函数
2.自定义函数
三.函数的参数
1.形式参数定义
2.实际参数定义
3.实参与形参的关系
四.函数的调用
1.传值调用
2.传址调用
3.怎么选择
五.总结
说起函数,我们最先想到的肯定是数学上的函数,而且这些函数问题在数学上可以说是把我们折磨的生不如死。但是你知不知道,C语言中也有一种函数,这个函数和数学上的函数有很多相似之处,同时也是学习C语言所必须掌握的知识。
函数的定义
C 语言中的函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的参数,也可以不接收;将代码段封装成函数的过程叫作函数定义。如果有返回值,在函数体中使用 return 语句返回。return 出来的数据的类型要和接收值的数据类型一样。
什么是库函数呢?
C语言标准规定:
随后由编译器厂商根据这些规定来制作这一系列函数,并将其放在标准库中,因此称作库函数。
像我们常用的scanf,printf,strlen等等这些编译器自带的函数,都是库函数。
这里提供给小伙伴们一个网站,可以让你了解到C语言中全部的库函数:https://cplusplus.com/reference/
这里简单的总结一下,C语言常用的库函数有:
一些功能相近的库函数,他们都会放入同一个头文件中,因此想要使用这些库函数,就必须先调用他们所在的头文件,比如我们常用的
库函数虽然好用,但是并不能满足我们编程的所有需求,这时候,就需要程序员来自定义函数了。
自定义函数组成:
ret_type fun_name(para1,*)
{
statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1 函数参数
这里我们举一个例子来具体讲解一下函数:
写一个函数,实现加法运算:
#include
int Add(int x,int y)
{
int sum = 0;
sum = a + b;
return sum;
}
int main()
{
int a = 2;
int b = 5;
int sum = Add(a,b);
printf("%d",sum);
return 0;
}
如上函数,int为此函数的返回类型,意为这个函数返回值是一个整型,这时候就需要用到return来具体实现返回你的sum。
这里要注意一点,当函数返回值不为空时,要在主函数用定义一个与返回值类型相同的变量来接收。
Add为函数名,创建函数名时,尽量要用这个函数实现的功能的英文来命名,这样更容易能够让别人读懂你这个函数是干什么的。
int x,int y,是这个函数所需要的两个参数,用来接收所传进来的值,并在函数语句中来使用操作。
其中,函数的返回类型和参数都是根据你的实际需求而可有可无的,例如下述函数:
#include
void print()
{
printf("hello world!");
}
int main()
{
fun();
return 0;
}
函数的返回类型也可以是void,也就是不返回任何值。
也可以不需要参数,仅仅实现一个打印“hello world!”的功能。
函数的参数分为两种:
写一个函数,实现两个整数的交换:
#include
void Swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
}
int main()
{
int a = 2;
int b = 5;
Swap(a, b);
printf("%d %d", a, b);
}
小伙伴们猜一下,这个函数真的能实现a和b的值的交换吗?
答案是并不能。
这是为什么呢???
我们在上述函数定义中所定义的 x 和 y 称为形式参数,而传进函数的 a 和 b 则称为实际参数。
我们来看上图,小伙伴们有没有发现,我们虽然让 x 和 y 分别接收了 a 和 b 的值,但是它们的地址并不相同。
小伙伴们不要忘了,main也是一个函数,在不同的函数中所创建的变量,所处的地址肯定就不会相同了,因此 x 和 y 仅仅是接收到了 a 和 b 的值,但并没有接收到 a 和 b 的地址。
在函数外如果不通过地址来改变这个变量的值,是不会使变量本身的值发生改变的。
因此,形式参数仅仅是实际参数的一次临时拷贝,对形式参数进行任何修改,都不会影响到实际参数。
那我们就无法通过函数来实现交换了吗???
当然可以,既然在不同的函数中想改变一个值需要地址,那我们就用地址来操作呗:
#include
void Swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int main()
{
int a = 2;
int b = 5;
Swap(&a, &b);
printf("a = %d b = %d", a, b);
}
如上函数,我们知道,指针是通过直接接收变量的地址来进行操作的,所以我们将函数的形参定义为两个指针变量,并给函数传入 &a 和 &b 两个地址来供其接收,然后我们在通过对两个指针变量的值进行交换,就能够轻松搞定啦。
再来看此时 x 和 y 的地址,是不是就跟 a 和 b 一样啦。
实例如下:
#include
void Swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
}
int main()
{
int a = 2;
int b = 5;
Swap(a, b);
printf("%d %d", a, b);
}
实例如下:
#include
void Swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int main()
{
int a = 2;
int b = 5;
Swap(&a, &b);
printf("a = %d b = %d", a, b);
}
那么我们到底该怎么区分又该怎么选择到底是传值还是传址呢???
很简单,如果你的函数进行的操作要求要对实参造成改变,就用传址调用,不需要对实参造成改变,就用传值调用。要学会在不同的应用场景做出正确的选择。
本期函数知识(上)到此就要结束啦,关于函数知识(下)的内容,一起来先睹为快:
对博主文章有任何问题和知识补充的,欢迎小伙伴们评论私信。
喜欢博主文章的小伙伴们不要忘记一键三连哦,我们下期再见!