这篇笔记主要是介绍C语言中的函数,包括函数的功能和定义等。阅读本文预计需要 6 分钟。
Day05 郝斌C语言自学视频之C语言的函数
- 为什么需要函数
- 什么是函数
- 函数的分类
- 如何定义使用函数
- 定义函数
- 如何在软件开发中合理的设计函数来解决实际问题
- 变量的作用域和存储方式
- 常用的系统函数
- 后记
为什么需要函数
函数是C语言的基本单位,类是Java,C#,C++的基本单位。函数
是继学习 C 语言流程控制
之后的第二个重点。那么前人为什么会创造函数?我们为什么需要函数呢?主要是以下两个原因:
-
使用函数可以避免重复性操作。
-
使用函数有利于程序的模块化。
例 函数的作用
/*
时间:2020年2月22日14:01:19
功能:
函数的作用演示
总结:
1. 函数可以实现功能复用,减少代码量
*/
# include <stdio.h>
// max 是函数名字,i 和 j 是形式参数,简称形参 void 表示函数没有返回值。
void max(int i, int j)
{
if (i > j)
printf("%d\n", i);
else
printf("%d\n", j);
}
int main(void)
{
int a, b, c, d, e, f;
a = 1, b = 2, c = 3, d = 9, e = -5, f = 100; // 不推荐这么写
max(a, b);
max(c, d);
max(e, f);
/*
if (a > b)
printf("%d\n", a);
else
printf("%d\n", b);
if (c > d)
printf("%d\n", c);
else
printf("%d\n", d);
if (e > f)
printf("%d\n", e);
else
printf("%d\n", f);
*/
return 0;
}
/*
在VSCode中的输出结果是:
--------------------------
2
9
100
--------------------------
*/
什么是函数
逻辑上:函数是能够完成特定功能的独立的代码单元。
物理上:函数能够接收数据,对接收的数据进行处理,将数据处理的结果返回,当然也可以不返回任何值。
总结:函数是一个工具,它是为了解决大量类似问题而设计的。函数可以当做一个黑匣子。
函数的分类
函数按照不同的分类方法,可以分为以下类型:
- | - |
---|---|
有参函数 | 无参函数 |
有返回值函数 | 无返回值函数 |
库函数 | 用户自定义函数 |
值传递函数 | 地址传递函数 |
普通函数 | 主函数(main函数) |
如何定义使用函数
定义函数
格式:
函数的返回值 函数的名字(函数的形参列表)
{
函数的执行体
}
函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体方法。
return 表达式;
的含义:
- 终止被调函数,向主调函数返回表达式的值。
- 如果表达式为空,则只终止函数,不向主调函数返回任何值。
break
是用来终止循环和switch
的,return
是用来终止函数的。
例 break VS return
/*
时间:2020年2月22日15:31:31
功能:
break VS return
总结:
break 终止循环和 switch,return 终止函数。
*/
# include <stdio.h>
void f(void)
{
int i;
for (i=0; i<5; ++i)
{
printf("大家辛苦了!\n");
// break; // 终止循环
return; // 终止函数
}
printf("同志们好!\n");
}
int main(void)
{
f();
return 0;
}
/*
break 时在VSCode中的输出结果是:
--------------------------
大家辛苦了!
同志们好!
--------------------------
return 时在VSCode中的输出结果是:
--------------------------
大家辛苦了!
--------------------------
*/
注意:函数返回值的类型也称为函数的类型。因为如果函数名前的返回值类型和函数执行体中的 return 表达式
中表达式的类型不同的话,则最终函数返回值的类型以函数名前的返回值类型为准。
例 函数返回值类型的决定因素
/*
时间:2020年2月22日15:26:21
功能:
测试 函数返回值类型由谁决定
总结:
如果函数名前的返回值类型和函数执行体中的 `return 表达式` 中
表达式的类型不同的话,则最终函数返回值的类型,
以函数名前的返回值类型为准。
*/
# include <stdio.h>
int f(void)
{
return 10.5; // 因为函数的返回值类型是 int
// 所以最终 f() 返回的是 10 而不是 10.5
}
int main(void)
{
int i = 99;
double x = 6.6;
i = f();
x = f();
// printf("%d\n", i);
printf("%lf\n", x);
return 0;
}
/*
在VSCode中的输出结果是:
--------------------------
10.000000
--------------------------
*/
注意事项
- 一个程序必须有且仅有一个主函数,即
main
函数。 - 主函数可以调用普通函数,普通函数不能调用主函数。
- 普通函数可以相互调用。
- 主函数是程序的入口,也是程序的出口。
- 形参和实参个数必须相同,位置一一对应,数据类型必须兼容。
- 函数调用和函数定义的顺序问题。如果函数调用写在了函数定义的前面,则必须加函数前置声明。
函数前置声明的作用:
- 告诉编译器即将可能出现的若干个字母代表的是一个函数.
- 告诉编译器即将可能出现的若干个字母所代表的的函数的形参和返回值的具体情况。
- 函数声明是一个语句,末尾必须加分号。
- 对库函数的声明是通过
# include <库函数所在的文件的名字.h>
来实现的
如何在软件开发中合理的设计函数来解决实际问题
- 一个函数的功能尽量独立,单一。
- 多学习,多模仿牛人的代码。
例 函数功能单一的优势
/*
时间:2020年2月24日11:25:24
目的:
求 1 到某个数字之间的所有素数,并将其输出
总结:
把函数功能进行拆分,一个功能一个函数,代码量更少,可重用性更高
*/
# include <stdio.h>
# include <stdbool.h>
// 本函数的功能是:判断m是否是素数,是返回true,不是返回false
bool IsPrime(int m)
{
int i;
for (i=2; i<m; i++)
{
if (0 == m%i)
break;
}
if (i == m)
return true;
else
return false;
}
// 本函数功能是把 1-n 之间所有的函数在显示器上输出
void TraverseVal(int n)
{
int i;
for (i=2; i<=n; ++i)
{
if (IsPrime(i))
printf("%d\n", i);
}
}
int main(void)
{
int val;
scanf("%d", &val);
TraverseVal(val);
return 0;
}
/*
在VSCode中的输出结果是:
--------------------------
10
2
3
5
7
--------------------------
*/
变量的作用域和存储方式
变量按作用域分为全局变量
和局部变量
。
变量按变量的存储方式分为:静态变量、自动变量和寄存器变量。
全局变量:在所有函数外部定义的变量叫全局变量。全局变量使用范围:从定义位置开始到整个程序结束。
局部变量:在一个函数内部定义的变量或者函数的形参,都统称为局部变量。
如:
void f(int i)
{
int j= 20;
}
i
和 j
都属于局部变量。局部变量使用范围:只能在本函数内部使用。
注意全局变量和局部变量命名冲突的问题
在一个函数内部如果定义的局部变量的名字和全局变量名一样时,局部变量会屏蔽掉全局变量。
常用的系统函数
系统函数 | 说明 |
---|---|
double sqrt(double s); | 求 x 的平方根 |
int abs(int x); | 求 x 的绝对值 |
double fabc(double x) | 求 x 的绝对值 |
推荐书籍 机械工业出版社《turboc 2.0实用大全》
注:递归(需要先理解栈),初学者可以先跳过。具体可以参看郝斌老师的数据结构视频。
【说明】
-
本学习笔记整理自B站郝斌老师的《郝斌C语言自学教程》片段P104-P120。
-
笔记中所有代码均在windows10操作系统,在VSCode编辑器中通过测试。具体VSCode C语言开发环境搭建方法请参照我的另一篇CSDN博客——Windows10下利用Visual Studio Code搭建C语言开发环境。
后记
如果对你有所帮助,欢迎关注我的公众号。这个公众号主要是慢慢分享和记录自己学习编程的笔记,比如:C,Python,Java等。后续也会分享自己面试以及在职场上的成长心得。
更多推荐
Day05 郝斌C语言自学视频之C语言的函数
发布评论