项目八 任务一 初识函数

项目八 函数

项目概述:
在前面的任务,我们其实已经接触过一些函数,比如项目一c程序的介绍的时候说过的main函数,数据类型的时候又学过标准的输出printf()函数和输入函数scanf()函数,可以这样说c程序的大多数的功能都是依靠函数来实现的,本项目将会学到函数的定义,以及函数的调用,以及函数的参数的使用,以及函数返回值的使用,通过本项目的学习,读者应该能够将实现特定功能的代码封装起来,从而简化代码,提高代码的可读性,大大提高我们的编程能力。
项目目标
掌握函数的概念
掌握函数的定义以及调用
掌握局部变量与全局变量
掌握函数参数的使用
掌握函数返回值的使用

任务一 初识函数

任务描述
假设有一个游戏程序,程序在运行过程中,要不断使用必杀技。不断使用必杀技的代码,在每次实现必杀技的时候都要执行这样的代码,使用必杀技的功能都是不断重复的代码,这样程序会变得很臃肿,可读性也非常差。为了解决代码重复编写的问题,可以实现必杀技的代码提取出来放在一个{}中,并为这段代码起个名字,这样在每次必杀技的地方通过这个名字来调用必杀技的代码就可以了。
在C语言中,大多数功能都是依靠函数来实现,本任务将针对函数的定义、调用进行相关讲解,通过本任务的学习,能够定义函数并且会调用函数。
学习目标
掌握函数的定义与声明。
掌握函数的调用方式。
掌握局部变量与全局变量。
相关知识

8-1-1 为什么会有函数

基于前一部分任务的学习,我们已经能开发一些功能简单的小程序了,但随着程序功能的增多,代码量随之增大,此时仍不加区分地把所有功能的实现代码放到一起,将会使得程序得组织结构不清晰,可读性变差,且程序中需要频繁使用同意功能时,只能重复编写该功能的实现代码,日积月累,程序将变得冗长,并且当某一功能需要修改时,又不得不找出所有定义及使用这段功能的地方修改之,管理维护的难度极大。
我们完全可以从现实生活中找到简化程序设计的方案:比如一个修理工会事先准备好螺丝刀,锤子等工具,这样在进行修理的过程中,需要用到拧螺丝的功能时就直接拿来螺丝刀使用,需要用到锤击物体的功能时就直接拿来锤子使用,无需临时制造,这个例子的核心在于“事先准备好工具”,遇到应用场景时,“拿来就用”。
在程序中,具备某一功能的工具指得就是函数,“事先准备工具”的过程即函数的定义,“拿来就用”即函数的调用。
在C 语言中, 函数分为以下 2 种:
1.库函数。由系统、或第三方库提供,直接调用即可,无需关心函数内部实现,例如: printf()、strlen()等函数,前面的学习我们早已经接触过库函数。
2.自定义函数。由程序员自己手动封装,需要实现函数内部功能。
接下来我们就要来实现自定义函数。
8-1-2 函数的定义
在C语言中,定义一个函数的具体语法格式如下:
返回值类型 函数名(参数类型 参数名1,参数类型 参数名2,……,参数类型 参数n)
{
执行语句
………
return 返回值;
}
例如我们使用的main函数
int main(int argc, char **argv){
return 0;//返回值
}
int 是返回值类型 main是函数名 int argc, char **argv是形参列表
接下来对上述语法格式进行简要说明,具体如下:
(1)返回值类型:
函数返回值的数据类型,可以把函数的数值返回该调用函数,可以是数据类型的一种,也可是是没有返回,如果没有返回值可以写void;
(2)函数名:
函数的名称,函数名是标示符在命名函数的要遵守标识符的命名规则;
(3)参数类型和参数名:
用于接收调用方法时传入的数据,在函数既可以有参数,也可以没有参数;
(4)return关键字:
返回函数指定类型的值,在函数中既可以有返回值,也可以没有返回值;
为了更方便理解(3)和(4)函数的关于参数和返回值的有无形式分类如下表8-1所示
表 8-1 函数的分类
无返回值	有返回值无参数	void 方法名(){}	返回值类型 方法名(){}有参数	void 方法名(形参列表){}	返回值类型 方法名(形参列表){}

(5)函数体
函数体是用一对花括号括起来的语句序列,函数的功能就是在这里实现的。
实例8- 1定义一个求和的函数。
要求如下:返回值是int 类型,函数名sum,形参列表int x,int y,函数体里面求和x+y;返回值是两个的和。
int sum(int x,int y){
return x+y;
}
注意:
一是函数名,是标识符要遵守标识符的命名规则,最好做到见名知意。
二是参数个数,一般是越少越好。
三是注释,多写注释有助于别人识别函数的作用。
四是函数名后面小括号中的参数,本质上就是局部变量,在该函数被调用(函数的调用后面就来讲)时,由外部为该参数变量进行赋值。
8-1-3 函数的调用
定义函数的目的为了使用函数,使用使用函数一词非专业用语,C语言中被称为调用函数,在C语言中函数类型不同,调用方式也不相同。
函数调用的一般形式为:函数名 (参数列表);
如果要调用的函数没有参数,则不用传递参数列表;如果有参数,就要按照顺序和类型传递参数,参数之间用逗号分隔。
1.无参数的函数的调用
下面通过例子来了解函数调用。
实例8- 2 无参的函数的调用

#include <stdio.h>
void func()	//定义 show 函数
{
  printf("func的无参函数 helloc");	//输出“helloc”
}
int main()
{
    func();	//调用 func函数
    getchar();
    return 0;
}

输出的结果如图 8-1所示:
在这里插入图片描述

图8- 1实例8-2无参数函数
下面通过一张流程图来说明上面例子中函数的调用过程如图8-2所示。
在这里插入图片描述
图8- 2 无参的函数被调用的流程
2.有参数函数的调用
实例8- 3 有参的函数的调用

#include <stdio.h>
void func(int x,int y)	//定义 func函数,形参为 num
{
printf("有参数的函数被调用x=%d, y=%d",x,y);	//输出形参 x数值
}
int main()
{
    func(100,200);	//调用 show 函数,传入 100 getchar();
    getchar();
    return 0;
}

输出的结果如图8-3所示:
在这里插入图片描述

图8- 3 实例8-3无参数函数
下面通过一张流程图来说明上面例子中函数的调用过程如图8-4所示。
在这里插入图片描述
图8- 4 有参的函数被调用的流程
8-1-4 函数的声明
C语言代码由上到下依次执行,原则上函数定义要出现在函数调用之前,否则就会报错。但在实际开发中,经常会先使用他们然后在定义,这个时候就需要提前对被调用的函数进行声明,也叫做函数的原型。
通俗一点讲,就是告诉C程序我要使用这个函数,虽然现在没有定义但是我们会在后面定义,你就别报错了。
函数声明的格式非常简单,其实就是去除函数的函数体,如下所示:
返回值类型 函数名(参数类型 参数名1,参数类型 参数名2,……,参数类型 参数n);
也可以不写形参,只写数据类型例如:
返回值类型 函数名(参数类型 ,参数类型,……,参数类型n);
有了函数声明,函数定义就可以出现在任何地方了,不论调用函数的前面还是后面都是可以的。
实例8- 4定义一个求两个数的sum(),将此函数放到调用函数的后面。

#include <stdio.h>
int sum(int a, int b );  //也可以写作int sum(int, int);
int main()
{
    sum(100,200);	//调用 show 函数,传入 100 
    getchar();
    return 0;
}

//函数定义

int sum(int a, int b){
	printf("我是定义在main函数后面的函数\n因为函数声明了所以也可以被调");
    printf("a=%d,b=%d\n",a,b);
    printf("a与的b的和为%d",a+b); 
    return 0;
}

运行结果如图8-5所示
在这里插入图片描述

图8- 5 实例8-4的运行结果

我们在调用函数之后定义了sum()函数,编译器在它前面虽然没有发现函数定义,但是发现了函数声明,程序就不会报错了。
8-1-5 局部变量和全局变量
1.局部变量
定义在函数内部的变量被称为局部变量。局部变量只能在当前函数中访问,不能跨函数访问。
下面通过案例来使用局部变量
实例8- 5 局部变量的声明。

#include<stdio.h>
void func()
{
int a=10;	//局部变量 a
}
int main()
{
func();
printf("%d",a);//出错代码因为局部变量只能在当前函数中访问,不能跨函数访问
getchar();
return 0;
}

运行代码,程序直接报错,如下图8-6所示。
在这里插入图片描述

图8- 6 实例8-5的运行报错

2.关于局部变量的使用说明:
(1)函数内部的局部变量不能被其他参数操作;
(2)函数的形参在函数内部可以当成普通变量看待,还是局部变量。
3.全局变量
定义在函数外部的变量被称为全局变量。
下面通过案例来使用全局变量
实例8- 6全局变量的声明和使用。

#include<stdio.h>
int a=10;	//全局变量变量 a
void func()
{
printf("func的a=%d",a);//func函数可以使用
}
int main()
{
func();
printf("main的a=%d",a);	//main函数也可以使用,因为a是全局变量
getchar();
return 0;
}

结果如图8-7所示。
在这里插入图片描述

图8- 7 实例8-6所示全局变量的使用
4.变量的作用域
变量的使用,应该在变量的作用的范围内才可以被使用,这个作用域称为变量的作用域。
局部变量,系统不会对其默认初始化,使用局部变量之前必须对局部变量初始化后才能使用,否则,程序运行后可能会异常退出,所有说局部变量的作用域在变量定义的方法内。
全局变量,如果不初始化,系统会自动对其初始化。并且他的使用可以在任意一个方法里,它的作用域是整个程序。
接下来我们通过一个案例来了解,全局变量的默认值。
实例8- 7 全局变量的基本数据类型的默认值。

#include <stdio.h>
int	a;
char	b;
double	d;
float	f;
int main()
{
	printf( "int 类型的默认值是:%d \n", a );
	printf( "char类型的默认值是:%c \n", b );
	printf( "double类型的默认值是:%f \n", d );
	printf( "float类型的默认值是:%lf \n", f );
	return(0);
}

运行结果如下图8-8所示。
在这里插入图片描述

图8- 8 实例8-7所示全局变量的使用

上述案例打印出了,基本数据类型默认是,现总结如下表8-2所示。
表 8-2 成员变量数据类型的默认值
成员变量类型 初始值

short	0
int	0
long	0
float	0.000000
double	0.000000
char	0'\u0000'(表现为空)

猜你喜欢

转载自blog.csdn.net/qq_27248989/article/details/106130724