作者:阿辉不一般
你说呢:生活本来沉闷,但跑起来就有风
专栏:爱上C语言
作图工具:draw.io(免费开源的作图网站)
如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主,如有不足还请指点,博主及时改正,感谢大家支持!!!
大家好啊!今天阿辉将为大家介绍C语言中的函数,✍包括函数的分类、参数、调用、函数嵌套调用和链式访问以及函数的定义和声明,内容干货满满,接下来就跟着阿辉一起学习吧
函数那不是数学里的东西吗?
不不不,今天阿辉要分享的是C语言中的函数。
在C语言中函数又称为子程序,是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
一般函数有参数、返回值和函数名。
C语言标准中规定了C语言的各种语法规则,C语言并不提供库函数;C语言的国际标准ANSIC规定了⼀些常用的函数的标准,被称为标准库,那不同的编译器厂商根据ANSI提供的C语言标准就给出了⼀系列函数的实现。这些函数就被称为库函数。
例如:
在屏幕上按一定格式打印信息的库函数(printf)
计算字符串长度的库函数(strlen)
用来生成随机数的库函数(rand)
这些库函数能提高我们程序的可移植性和我们编写程序的效率,库函数有很多难道都得背下来吗?这不现实,我们可以通过C plus plus这个网站学习库函数
比如在这个网站中我们看一看strilen
这个库函数
这个网站对于我这种菜鸟是不够友好的,它全部都是英文,但是咱们也不要因噎废食
我们可以使用网页翻译,但阿辉觉得学习英语是非常用必要的
阿辉英语也很菜,一起加油吧!
用库函数记得引对应的头文件
上面我们介绍了库函数,自定义函数才是重头戏,因为有许多的功能都需要我们程序员自己来设计,仅仅靠库函数是不够的。
同样的自定义函数与库函数一样都有返回类型,函数名和参数
type fun_name(para)
{
statement;//语句
}
type返回类型
fun_name函数名
para参数
当函数不需要返回值时返回类型要用void
,不需要参数时括号内要用(void)
如果省略这些的话可能会出bug
举例:找两个数中较大的一个
#include
int num_max(int a, int b)
{
return (a > b) ? a : b;
}
int main()
{
int a = 20;
int b = 10;
int max = num_max(a, b);
printf("%d\n", max);
return 0;
}
自定义函数时函数的名字要起的有意义,别人在读你的代码时就会更加舒服
上述代码中函数部分用到了三目操作符(也叫做条件操作符),那我们就简单介绍一下吧
三目操作符的语法规则
conditon?exp 1:exp 2;
其中,contion
是条件表达式,当条件表达式为真(非0值)时执行表达式exp 1
,为假(值为0)时执行表达式exp 2
函数的参数有实际参数和形式参数
例:
#include
int num_max(int a, int b)
{
return (a > b) ? a : b;
}
int main()
{
int a = 20;
int b = 10;
int max = num_max(a, b);
printf("%d\n", max);
return 0;
}
实参:真实传给函数的参数就是实参,实参可以是常量
,变量
,表达式
,函数
,无论实参是何种类型在函数调用时他们都必须由确定的值,以便把值传给形参
例如:上述代码中int max = num_max(a, b)
中的a
和b
都是实参
形参:函数用来接收实参的参数就是形参,也就是函数名后面括号里的变量,形参只有在函数调用时才被创建(实例化分配内存空间),出了函数就被销毁,函数调用结束形参的生命周期也结束了。
形参只在函数中起作用,形参只是实参的一份临时拷贝
例如:上述代码中int num_max (int a, int b)
中的a
和b
就是形参
函数的调用分为:传值调用和传址调用
他们有什么区别呢?我们接着来看
传值调用:形参和实参分别占有不同的内存块,改变形参并不会影响实参。
简单来说就相当于在函数内新创建了一个变量,只不过这变量的初始化内容就是传过来实参的值。
传址调用:是将函数外创建的变量的内存地址传给函数的一种函数调用方式。
这种调用方式真正的将函数与外部变量联系起来,也就是函数内部可以操作函数外部的变量。
综上:传值调用不能改变实参,传址调用可以改变实参
例:交换两个数
void exchange(int a, int b)
{
int tmp = a;
a = b;
b = a;
}
int main()
{
int a = 10;
int b = 20;
printf("交换前:a = %d b = %d\n", a, b);
exchange(a, b);
printf("交换后:a = %d b = %d\n", a, b);
return 0;
}
我们可以看到,由于是传值调用形参不能改变实参,所以两个数并没有被交换
因此,这里得使用传址调用
正确代码
void exchange(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = *a;
}
int main()
{
int a = 10;
int b = 20;
printf("交换前:a = %d b = %d\n", a, b);
exchange(&a, &b);
printf("交换后:a = %d b = %d\n", a, b);
return 0;
}
函数的嵌套调:就是在函数的内部调用其他函数
例如:
虽然函数可以嵌套调用,但并不能嵌套定义
函数的链式访问:就是把一个函数的返回值作为一个函数的参数
我们来看一个有意思的例子
#include
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
return 0;
}
大家不妨看看这个代码的运行结果是什么,没错屏幕上打印了4321
,怎么样你答对了吗?
库函数printf
的返回值是成功打印字符的个数,如果打印出错则返回负数
分析:程序从最里层的函数开始,首先,最里面的printf
打印了43
,返回值为2
,然后第二个printf
打印了2
,返回值为1
,然后最后一个printf打印了1
,所以最总屏幕上打印了4321
函数的定义:就是函数的具体实现
函数的声明:就是让编译器有这么个函数,函数名是什么,函数的返回值和参数又是什么
使用函数前要满足先声明后使用
函数的声明有以下两种方式:
函数原型式声明:
int fun(int a, int b); // 函数名字fun,返回类型 int,有2个int 参数
函数简单声明:
int fun(int, int); // 函数名字fun,返回值类型int,有2个int 参数
到这里,阿辉今天对于C语言函数的分享就结束了,希望这篇博客能让大家有所收获, 如果觉得阿辉写得不错的话,记得给个赞呗,你们的支持是我创作的最大动力