【918C++程序设计】3、 函数

3.1 函数的定义与调用

为什么需要函数

函数时程序的重要组成部分,每个程序都必须有一个主函数(main函数)。“函数”这个名词是从英文function翻译过来的,function愿意是“功能”,顾名思义,一个函数就是一个功能
一个较大的程序不可能完全由一个人从头到尾地完成,更不可能把所有内容都放在一个主函数中,一般把一个大的程序划分为若干个程序模块(即程序文件),但一个程序只能由一个main函数
在程序进行编译时,以程序文件模块为编译单位,即分别对每一个编译单位进行编译。
在实际应用的程序中,主函数写得很简单,他的作用就是调用各个函数,相当于总调度。

函数的分类

(1)系统函数,即库函数。由编译系统提供的。
(2)用户自己定义的函数:无参函数、有参函数。

无参函数形式:
类型名 函数名([void])
{
声明部分
执行语句
}

有参函数形式:
类型名 函数名(形式参数表列)
{
声明部分
执行语句
}

3.2 函数的参数传递、返回值

形式参数和实际参数

形式参数:在定义函数时函数名后面括号中的变量名称。
实际参数:在主函数中调用一个函数时,函数名后面括号中的参数(可以是一个表达式)。

(1)在定义函数时指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。
(2)实参可以是常量、变量或表达式。
(3)在定义函数时,必须在函数首部指定形参的类型。
(4)实参与形参的类型应相同或赋值兼容。
(5)实参变量对形参变量的数据传递是“值传递”,即单向传递。

函数的返回值

通过函数的调用使主调函数能得到一个确定的函数值,这就是函数的返回值。
(1)函数的返回值是通过函数中的return语句获得的。
(2)函数值的类型。在定义函数时,指定函数值的类型。函数类型决定返回值类型。

3.3 变量的作用域和生存期

局部变量

在一个函数内部定义的变量是内部变量,它只在本函数范围内有效。
(1)主函数中定义的变量也只在主函数中有效。
(2)不同函数中可以使用同名的变量。
(3)可以在一个函数内的复合语句定义变量,这些变量只在复合语句内有效。
(4)形式参数也是局部变量。
(5)在函数原型声明中出现的参数名,只在原型声明中的括号范围内有效,不能被引用。

全局变量

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

存储方法

静态存储:在程序运行期间,系统对变量分配固定的存储空间。
动态存储:在程序运行期间,系统对变量动态地分配存储空间。

内存中供用户使用的存储空间可以分为3部分:
1、程序区
2、静态存储区
3、动态存储区

程序区用的数据分别放在静态/动态存储区中:
全局变量全部放在静态存储区中,在程序开始执行时给全局变量分配存储单元,程序执行完毕就释放这些空间。
动态存储区存放以下数据:
1、函数形式参数。在调用该函数时给形参分配存储空间
2、函数中定义的变量(未加static的局部变量)
3、函数调用时的现场保护和返回地址

存储类别

auto:自动的
static:静态的
register:寄存器的
extern:外部的

自动变量
不用static声明的局部变量,可加可不加auto

用static声明静态局部变量
在下一次调用该函数时,该变量仍保持上一次函数调用结束时的值
(1)静态局部变量在静态存储区内分配存储单元
(2)对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。
(3)若定义时不赋初值,则编译时自动赋0/空字符
(4)其他函数不可引用

用static声明静态外部变量
用static声明的外部变量(全局变量)只限于被本文件引用,而不能被其他文件引用。
PS:是否用static声明的外部变量,都是静态存储方式。

用register声明寄存器变量
需要频繁使用的变量,为提高执行效率,存放在CPU的寄存器中,提高执行效率。
PS:如今编译系统能够识别频繁使用的变量,自动将其放在寄存器中,因此实际中不需要用register声明。

用extern声明外部变量
有时需要用extern来声明全局变量,以扩展全局变量的作用域。

1、在一个文件内声明全局变量
提前引用声明:前文想引用后文定义的全局变量,需前文先引用声明,后文再赋值。

extern int a,b;
cout<<a+b<<endl;
int a=1,b=2;

2、在多文件的程序中声明外部变量
外部变量声明:在一个文件中想引用另一文件中已定义的外部变量。
一个文件中定义变量赋值,另一文件相用时先用extern声明。

一个联系

函数也分为内部和外部

static int fun1()
extern int fun2()

static只能被本文件调用,extern可供其他文件调用(不加static就默认extern)。

3.4 函数的递归调用

在调用一个函数的过程中又出现直接或间接地调用函数本身。
间接:f1调用f2,f2调用f1

递归过程中必须具有一个结束递归过程的条件

3.5 函数的重载、内联及默认参数

函数的重载

同一个函数名定义多个函数,这些函数的参数个数和参数类型可以不相同。这就是“一物多用”。
重载函数的参数个数参数类型参数顺序三者中必须至少有一种不同。

函数的内联(内置)

在编译时将所调用函数的代码直接嵌入到主调函数中,而不是将流程转出去。
内置函数中不能包括复杂的控制语句,如循环语句和switch语句。一般只将规模很小(5个语句以下)而频繁使用的函数声明为内置函数。
可以在声明和定义函数时同时写inline,也可以只在函数声明时加。

函数的默认参数

float area(float a=6)
main(){
area()//此时a为6
area(7.5)//也可另给出a值
}

当有多个参数时,默认参数放在最右边

void fun(int a,int b,int c=0,int d=2)
fun(3,5,1)//此时d为默认的2
fun(3,5)//此时c为默认0,d为默认2

(1)如果函数的定义在函数调用之前,则应在函数定义中给出默认值;如果函数定义在函数调用之后,则在函数调用之前需要有函数声明,且在声明时给出默认值,函数定义时可以不给出默认值。
(2)一个函数不能既作为重载函数,又作为有默认参数的函数

3.6 函数模板

建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。

template<typename T>
T max(T a,T b){
if a>b 
return a;
else
return b;
}
int main(){
double d1,d2;
float f1,f2;
max(d1,d2);//此时T为double
max(f1,f2);
}

通用模板的一般形式

template<typename T>template<class T>

3.7 头文件与多文件结构

头文件

(1)对类型的声明
(2)函数声明
(3)内置函数的定义
(4)宏定义:用#define定义的符号常量和用const声明的常变量
(5)全局变量定义
(6)外部变量声明
(7)其他头文件

头文件是不同源文件之间的接口

#include <math.h>//C形式
#include <math>//C++形式

一般标准库提供的,不加.h,自己编写头文件添加.h

3.8 编译预处理

详见:编译预处理详述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值