C语言基础:第10天笔记
内容提要
-
函数
-
函数的概述
-
函数的分类
-
函数的定义
-
形参和实参
-
函数的返回值
-
函数
函数的概述
-
函数:实现一定功能的,独立的代码模块,函数是c程序的核心构成模块,可以说c程序就是由众多的函数组成,对于函数的使用,一定是先定义,后使用。
-
使用函数的优势:
①可以通过函数提供给别人使用,也可以使用别人提供的函数,减少代码量。
②借助函数可以减少重复性的的代码。
③实现结构化(模块化)程序设计思想
关于结构化设计思想:将大型的任务功能划分为相互独立的小型的任务模块来设计。
-
函数是C语言程序的基本组成单元:
C语言程序是由一个或多个函数组成
函数的分类
-
从函数实现的角度:
-
库函数:C语言标准库实现的并提供使用的函数,比如:
scanf() printf() fgets() fputs() strlen()
-
自定义函数:需要程序员自行实现,开发中大部分函数都是自定义函数
-
-
从函数形式的角度:
-
无参函数:函数调用时,无需传递,可有可无返回值,举例:
test1();
-
有参函数:函数调用时,需要参数传递数据,经常需要配套返回值来使用,举例:
printf("%d\n",12);
-
-
从函数调用的角度:
-
主调函数:主动去调用其他函数的函数。(main函数只能作为主调函数)
-
被调函数:被其他函数调用的函数。
举例:
//主调函数 int main() { //被调函数 printf("hello world\n"); }
很多时候,尤其是对于自定义函数来说,一个函数有可能既是主调函数,又是被调函数。
int fun_b() { printf("hello\n"); } //主调函数 int fun_a() { printf("world\n"); //被调函数 fun_b(); } int main() { //被调函数 fun_a(); }
以上案例中,fun_b()来说是主调函数,同时对于main()函数来说,它又是被调函数。
-
函数的定义
定义
语法:
[返回类型] 函数名([形参列表]) ------函数头 | 函数首部 { 函数体语句; ------函数体,整个{}包裹的内容包括返回值都属于函数体,{}不能省略 }
函数头:
-
返回类型:函数返回值的类型,(返回值是被调函数的主调函数)
-
函数名:函数的名称,遵循标识符命名(不能以数字开头,只能包含字母、数字、下划线,建议:小写+下划线命名,举例:show_all())
-
形参列表:用于接收主调函数传递的数据,如果有多个参数,使用“,”分隔,且每一个形参都需要指明类型。
小贴士:
形参列表(被调函数):主调函数给被调函数传递数据,主调函数 → 被调函数
返回类型(被调函数):被调函数给主调函数返回数据,被调函数 →主调函数
说明:
-
函数的返回类型:就是返回值的类型,两个类型可以不同,但是必须能够进行转换,举例:
double fun_a() //函数的返回类型是double { return 12; //函数返回值是int }
以上代码可以理解为:将int类型的12赋值给一个double类型的匿名变量(int → double),此时属于隐式转换。
int fun_a() //函数的返回类型是double { return 12.5; //函数返回值是int }
案例:
-
在C语言中还可以定义无类型(void类型)的函数,这种函数不返回函数值(没有函数值),只是完成某种功能,举例:
void test() //此时这个函数没有返回值,也就是它的返回值是,return; { printf("hello\n"); } //下面等价于上面 void test() { return; //一般,这个return是省略不写的 }
-
在C语言中,函数的返回类型是可以省略的,如果省略,默认返回int,举例:
//写法1 main的返回类型是int类型,默认的返回值是0,等价于写法2 main() { ... } //写法2:main的返回类型是int类型,默认的返回值是0 int main() { return 0; // 0:逻辑真, -1:逻辑假 支持非0表示 }
-
函数中返回语句的形式为
return(表达式)
或者return 表达式
。//写法1 int main() { return(0); } //写法2 int main() { return 0; }
-
如果
参数列表
中有多个形式参数,则它们之间要用","分隔;即使它们的类型相同,在形式参数中只能逐个进行说明,举例://正确写法 int avg(int x, int y, int z) { ... } //错误示例 int avg(int x,y,z) { ... }
-
如果
形参列表
中没有参数,我们可以不写,也可以用void标识,举例://写法1 int main() { ... } //写法2 int main(void) { ... }
案例
案例1
-
需求:计算1~n之间自然数的阶乘
-
代码:
注意:这里计算结果为0是因为数据太大,超过int存储范围,数据丢失
案例2
-
需求:计算一个圆台两个面的面积之和。
-
方案1:自定义一个函数,直接计算两个圆的面积和
-
方案2:自定义一个函数,只计算一个圆的面积
-
代码:
/************************************************************************* > File Name: demo02.c > Author: > Description: > Created Time: 2025年03月14日 星期五 14时26分54秒 ************************************************************************/ #include <stdio.h> #include <math.h> #define PI 3.1415926 // 对库函数 extern double pow(double x,double y); /** * 定义一个函数,根据半径计算面积 * @param r :半径 * @return 面积 */ double cicle_area(double r) { return PI * pow(r,2.0);//编译的时候,需要在gcc后面加-lm } int main(int argc,char *argv[]) { // 定义两个圆半径和两个园面积 double r1,r2,area1,area2; printf("请输入两个圆的半径\n"); scanf("%lf,%lf",&r1,&r2); //计算面积 area1 = cicle_area(r1); area2 = cicle_area(r2); //输出 printf("一个园台两个面面积之和为:%.2f\n",area1 + area2); return 0; }
形参和实参
形参(形式参数)
函数定义时指定的参数,形参是用来接收数据的,函数定义时,系统不会为形参申请内存,只有当函数调用时,系统才会为形参申请内存,主要用于存储实际参数,并且当函数同时(执行return),系统会自动回收为形参申请的内存资源。
案例
-
需求:判断奇偶数
-
代码:
/** * 方式1 */ void fun(int n) { if(n % 2 == 0) { printf("%d是偶数\n",n); } else { printf("%d是奇数\n",n); } } /** * 方式2 推荐 */ void fun(int n) { if(n % 2 == 0) { printf("%d是偶数\n",n); return;//return之后代码不执行 } printf("%d是奇数\n",n); } /** * 方式3 推荐 */ int fun(int n) { if(n % 2 == 0) { printf("%d是偶数\n",n); return -1;//return之后代码不执行 } printf("%d是奇数\n",n); return 0; }
实参(实际参数)
定义
-
函数调用时主调函数传递的数据参数(字面量、符号常量、表达式...,是要是确定的值),实参就是传递的数据。
-
实参和形参必须类型相同,如果不同时,按赋值规定进行类型转换,比如隐式转换。
-
在C语言中,实参传递必须遵循
单向传递
(通过实参给形参赋值),实参只是将自身的值传递给了形参,而不是实参本身,形参的值的改变不会影响实参。int fun(int n) { printf("%d\n",n); } int main() { int a = 10; // a = 10 fun(a); // a是实参,数据10,实参是变量 a = 20; //a = 20 fun(12);//字面量12就是实参 fun(a + 12); //数据量是22 实参是表达式 }
-
实参与形参在内存中占据不同的内存空间。
double fabs(double a) { return a < 0 ? -a : a; } int main() { int x = 12,y = -12; int x1 = (int)fabs(x); //12 int y1 = (int)fabs(y); //12 }
案例
案例1:
-
需求:输入4个整数,要求用一个函数求出最大数
-
代码:
/************************************************************************* > File Name: demo03.c > Author: > Description: > Created Time: 2025年03月14日 星期五 15时25分32秒 ************************************************************************/ #include <stdio.h> /** * 定义一个函数,求两个数最大数 * @param x,y * @return 最大数 */ int max(int x, int y) { return x > y ? x : y; } int main(int argc,char *argv[]) { int a,b,c,d,max1,max2,max3; printf("输入4个数\n"); scanf("%d%d%d%d",&a,&b,&c,&d); //求ab max1 = max(a,b); //求abc max2 = max(max1,c); //求abcd max3 = max(max2,d); printf("%d,%d,%d,%d中最大%d\n",a,b,c,d,max3); return 0; }
函数的返回值
-
若不需要返回值,函数可以没有return语句。
//如果返回类型是void,return可以省略 void fun1 { } //return 可以省略,默认 0 int fun2() { } //return 可以省略,默认 0 fun3() { }
-
一个函数中可以有多个return语句,但任一时刻只有一个return语句被执行
int eq(int num) { if(num % 2 == 0) { printf("%d\n",num); return 0; } printf("%d\n",num); return 0; }
-
返回值类型一般情况下要和函数中return语句返回的数据类型一样,如果不一致,以函数定义时指定的返回值类型为标准。
案例
需求:输入两个整数,要求用一个函数求最大数
-
案例1:
/************************************************************************* > File Name: demo04.c > Author: > Description: > Created Time: 2025年03月14日 星期五 16时01分54秒 ************************************************************************/ #include <stdio.h> /** * 定一个函数 * @param x,y * @return max */ int get_max(int x, int y) { if (x > y) return x; return y; } int main(int argc,char *argv[]) { int a,b,max; printf("请输入\n"); scanf("%d%d",&a,&b); max = get_max(a,b); printf("%d,%d中最大数是%d\n",a,b,max); return 0; }
-
案例2
/************************************************************************* > File Name: demo05.c > Author: > Description: > Created Time: 2025年03月14日 星期五 16时01分54秒 ************************************************************************/ #include <stdio.h> /** * 定一个函数 * @param x,y * @return max */ double get_max(int x, int y) { if (x > y) return x; return y; } int main(int argc,char *argv[]) { int a,b,max; printf("请输入\n"); scanf("%d%d",&a,&b); max = (int)get_max(a,b); printf("%d,%d中最大数是%d\n",a,b,max); return 0; }
-
案例3:
/************************************************************************* > File Name: demo06.c > Author: > Description: > Created Time: 2025年03月14日 星期五 16时01分54秒 ************************************************************************/ #include <stdio.h> /** * 定一个函数 * @param x,y * @return max */ double get_max(int x, int y) { double z; z = x > y ? x : y; return (int)z; } int main(int argc,char *argv[]) { int a,b,max; printf("请输入\n"); scanf("%d%d",&a,&b); max = get_max(a,b); printf("%d,%d中最大数是%d\n",a,b,max); return 0; }
运行结果: