用函数实现模块化程序设计

本文详细介绍了C语言中如何使用函数实现模块化程序设计,涵盖了函数的声明、定义、调用及其过程,形式参数与实际参数的概念,以及函数的参数、变量的声明和定义,特别是关于数组作为参数的使用。同时,文章还讨论了局部变量和全局变量的作用域,动态存储与静态存储的区别,以及内部函数与外部函数的特性。通过一系列例题,进一步阐述了函数在实际编程中的应用。
摘要由CSDN通过智能技术生成


函数是C语言中实现特定功能的程序块,也叫程序模块。 每一个函数实现一个特定的功能,当其他函数需要这个功能时,调用该函数即可。
模块化程序设计的思路就是,事先设计好各个功能的模块,需要的时候采用组装的办法来简化程序的设计。
函数的操作,具体有: 函数的声明、函数的定义、函数的调用

函数的声明

把函数的有关信息通知编译系统,以便编译系统对程序进行编译时,知道它们是函数。具体信息包括:函数名、函数类型、函数参数的个数和类型

函数的定义

“先定义,后使用”
定义函数包括以下内容:

  1. 函数的名字
  2. 函数的类型
  3. 函数参数的名字和类型
  4. 函数的具体操作,即实现什么功能
  • 定义无参数的函数
    类型名 函数名()
    {
    函数体
    }
  • 定义有参数的函数
    类型名 函数名(形式参数列表)
    {
    函数体
    }

    例:
int max(int x, int y)	//函数类型为int整型,函数名为max,函数参数的名字为x、y,函数参数的类型为整型
//以下为函数的具体操作,此函数具体实现的功能为求两个数中的最大值
{
   						
	int z;
	z = x>y ? x : y;
	return z;
}

函数的调用

函数名(实参列表)
例:c = max(a, b);

形式参数与实际参数

对于有参数的函数,在函数定义阶段使用的参数为形式参数(例中的x和y),函数调用阶段使用的参数为实际参数(例中的a和b)
在函数的调用阶段,系统会将实参的值传递给被调用的函数的形参中,是**“值传递”**方式——数据传递的方向是从实参到形参,单向传递。形参与实参的数据类型应该相同,若有不同,实参的值会转换为形参的数据类型,再进行功能实现。

函数的调用过程

  1. 函数定义阶段到函数未被调用之前的这个阶段,函数中的形参不占内存中的存储单元。函数被调用时,形参才临时分配存储单元。
  2. 实参的值传递给形参。
  3. 执行函数功能,即运行函数体
  4. 通过return语句将函数运算的值返回调用函数。若函数不需要返回值,则函数的类型为void,且不需要return语句。
  5. 调用结束,形参单元被释放。实参的值从始到终是不会改变的,若形参的值发生改变,不会改变实参的值。这是因为形参和实参是两个不同的存储单元。

由以上调用过程可知,函数的调用必须在函数的声明之后。只有在声明之后,系统编译时才能识别到当前调用的是函数。
若被调用函数的定义在调用函数之前,则不用进行声明。因为函数定义时,系统以知道了这个函数的存在。

函数的声明与定义

函数的声明与定义的第1行基本相同,只是函数的声明多出了“;”号。
函数的声明是为了方便函数调用时,对其合法性进行检查。函数声明的是函数的原型
函数的定义是对函数功能的确定。函数的定义显然不在声明部分的范围内。

函数的参数

数组元素作为函数的实参

数组元素是可以作为函数的实参的,但数组元素不能作为函数的形参
因为形参的存储单元是函数被调用时临时分配的,而数组是一个整体,在内存中占一串连续的存储单元,所以形参不可能为单个数组元素分配存储单元。但数组元素的值是可以单独分配存储单元进行存储的(单个的数组元素与单个变量的概念是一样的)。所以数组元素可以作为函数的实参。

数组名作为函数的参数

函数的数组名即可以作为函数的实参,又可以作为函数的形参
形参数组可以不指定大小,在定义数组是在数组后跟一个空的方括号即可。
如:float average(float array[])

函数的变量

变量的声明和定义

定义性声明:简称定义,需要建立存储空间
引用性声明:简称声明,不需要建立存储空间

int a;		//既是定义,又是声明
extern a;	//只是声明
  1. 按作用域分
    在这里插入图片描述

  2. 按变量的生存期分
    在这里插入图片描述

  3. 从变量值存放的位置来分
    在这里插入图片描述

局部变量和全局变量(作用域)

  • 局部变量
    函数内部定义的变量、复合语句内定义的变量、形参都是局部变量。
    函数内部定义的变量,只在本函数范围内有效;复合语句内定义的变量,只在本复合语句范围内有效;形参是另一种形式的函数内部变量。

  • 全局变量
    在函数外部定义的变量称为外部变量,外部变量是全局变量。
    全局变量的有效范围是从定义变量的位置开始,到本源文件结束

  • 不建议频繁使用全局变量的原因

  1. 全局变量全程都占据存储单元
  2. 是函数的通用性降低。在使用改函数功能的同时,还必须考虑到它所调用的函数外的全局变量。不易迁移
  3. 降低了程序的清晰性

注:全局变量与局部变量重名时,在局部变量范围内,会使用局部变量。

动态存储和静态存储(生存期)

  • 静态存储
    程序运行期间由系统分配固定的存储空间,程序运行的整个过程变量值都是存在的
    全局变量全部存放在静态存储区中。

  • 动态存储
    程序运行期间根据需要进行动态的分配存储空间,函数调用结束后才存储单元马上释放,函数值就不存在了
    形参、函数中的自动变量都存放在动态存储区中。

数据的存储类别

C语言中,每一个变量和函数都有两个属性:数据类型和数据的存储类别。数据类型即整型、浮点型等;数据的存储类别指数据在内存中存储的方式。
C的存储类别包括4种:自动的(auto)、静态的(static)、寄存器的(register)、外部的(extern)

  • 自动变量(auto变量
    函数中的局部变量,若不专门声明为static(静态)存储类别,都是动态分配存储空间的。在调用该函数时,系统会自动分配存储单元,函数调用结束后就自动释放这些存储单元。因此这类局部变量被称为自动变量。自动变量的关键字auto是可以省略不写的。

  • 静态变量(static变量

    • 局部变量
      若希望局部变量的值在函数调用后依然保留,即不释放存储单位。可用关键字static进行声明,使其变为静态局部变量
    1. 静态局部变量属于静态存储类别,函数调用后不释放存储单元
    2. 静态局部变量只赋初值一次,以后每次调用函数不在重新赋初值,而是保留上一次函数调用结束时的值。
    3. 虽然静态局部变量在函数调用结束后仍存在,但其他函数是不能引用它的。因为它是局部变量,作用域只局限于本函数。
    • 全局变量
      全局变量都是存放在静态存储区中的,因此它们的生存期是固定的。但全局变量的作用域是不固定的。一般来说,外部变量的作用域是从变量的定义处开始,到本程序文件的末尾。但通过关键字的定义可将变量的作用范围扩展
      • 在一个文件内扩展外部变量的作用域(extern)
        外部变量遵循先定义、后使用的原则。若想在定义之前就引用外部变量,则应在引用前用关键字extern对该变量作”外部变量声明“,将该外部变量的作用域扩展到此位置。
      • 将外部变量的作用域扩展到其他文件(extern)
        若程序包括多个文件,某两个文件想共同引用同一个外部变量,则可以:在任一文件中定义外部变量A,在另一文件中用关键字extern对该变量进行”外部变量声明“
      • 将外部变量的作用域限制在本文件中(static)
        若希望某些外部变量只能被本文件引用,则使用关键字static进行声明,称为”静态外部变量
  • 寄存器变量(register变量)
    一般情况下,变量(静态存储方式和动态存储方式)的值都是存放在内存中的。如果一些变量使用频繁,为提高执行效率,允许将局部变量的值放在CPU中的寄存器中。用关键字register声明,被称为寄存器变量

内部函数与外部函数

  • 内部函数
    该函数只能被本文件中的其他函数所调用,由关键字static声明,又称为静态函数
    static 类型名 函数名(形参表);

  • 外部函数
    该函数可供其他文件中的函数所调用,由关键字extern声明。函数本质上都是外部的,所以extern可以省写
    **extern 类型名 函数名(形参表); **

例题汇总

例7.1初识函数

输出以下结果:

在这里插入图片描述

#include<stdio.h>
int main()
{
   
	void print_star();	//函数的声明,声明函数的原型
	void print_message();
	
	print_star();		//函数的使用,使用print_star函数,输出*号
	print_message();	//使用print_message函数,输出信息
	print_star();
	
	return 0;
}

void print_star()		//函数的定义,定义函数功能
/*print_star函数的主要作用是输出*号*/
{
   
	printf("********************\n");
}

void print_message()
/*print_message函数的主要作用是输出信息*/
{
   
	printf("How do you do!\n");
}

例7.2找最大值

输入两个整数,要求输出其中值较大者。

#include<stdio.h>
int main()
{
   
	int max(int x, int y);	//函数声明,告诉编译系统max为有两个参数的函数
	int a, b, c;
	
	printf("请输入两个整数:\n");
	scanf("%d%d", &a, &b);
	
	c = max(a,b);			//使用函数max比较两个数中的较大值
	
	printf("最大值为:%d", c);
	return 0;
}


int max(int x, int y)	//定义max函数,max函数有两个参数,且有返回值,返回值为int整形
{
   
	int z;				//局部变量,临时分配存储空间
	z = x>y ? x : y;	//将x,y中的较大值,赋值给z
	
	return z;			//返回z的值,释放临时存储空间
}

例7.3返回值类型自动转换

同上,求最大值

#include<stdio.h>
int main()
{
   
	int max(float x,float y);
	float a, b;
	float c;
	
	printf("请输入两个数:\n");
	scanf("%f%f", &a, &b);
	
	c = max(a,b);
	
	printf("最大值为:%f\n", c);
	return 0;
}

int max(float x,float y)	//max函数的参数为float浮点型,返回值为int整型
{
   
	float z;
	z = x>y ? x : y;
	return z;				//z虽为float浮点型,但max函数为int整型
}							//所以z的值会由float转换为int,舍弃小数点后的数

运行结果为:
7.3运行结果

例7.4求和

求两个实数的和

#include<stdio.h>
int main()
{
   
	float add(float x, float y);	//声明函数,让编译程序知道函数的相关信息
	float a, b, c;
	
	printf("输入两个实数:\n");
	printf(
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值