C筑基——函数利用
函数利用
一个程序即由一个main函数和若干其他用户自定义函数(完成特定功能的程序模块)组成;
通过定义函数创建可被重复使用的代码以简化程序
分类:库函数(系统提供)+自定义函数(用户按需定义)
定义函数的一般形式
1)无参函数版([]表示可省略)
执行时无需从主调函数调用数据进来
1 | /*这都是例子哈哈哈哈哈*/ |
2)有参数版
执行时需接收来自主调函数传来的数据,实参与形参的类型必须相同或者是相容的;
相容的意思就是float b可以直接转成int x,然后b顺利送到形参x;
字符型与整型可以互相通用。
1 | /* |
3)返回值的说明
一但执行return语句,则函数后面的语句都不再执行;
一个函数中可以有一个以上的return语句,执行到哪一个,哪一个起作用;
1 | int max( int x , int y ) |
函数的调用
主调函数:主动调用其他函数
函数的调用:主调对被调的调用
调用函数的形式:函数名([实参表列,用逗号分隔])
实参表列可省略不写,一般是那种无需传参的;
若被调函数位置在主调函数的下面,则在调用前先写一遍声明部分(也是就是函数首部,放在其他函数外面),要不不能正常编译,声明时不需要形参名和函数体,但要告知形参的个数和类型;
如
int max(int,int);,所以一般都写在前面,使结构更简单
1)调用方式
- 函数语句
不要求函数带回值,单独作为一个语句,如Luxsie();
- 函数表达式
出现在表达式中,要求带回一个确定值以参与运算,如c=2+max(a,b);
- 函数参数
函数调用作为另一个函数调用的实参,被调用函数必须存在,若调的main函数则要在程序开头引用,如#include<cmath>
嵌套调用
[!WARNING]
C++中不允许在一个函数中对另一个函数做完整定义,程序中的每一个定义平行而独立;
但可以在调用一个函数的过程中再去调用另一个(比如main调用f1,然后f1里调用一个f2)
递归调用
在调用一个函数的过程中又直接/间接的调用该函数本身,要格外注意什么时候调用结束【一般使用if语句来终止,包含此形式的成为递归函数】
1 | int age(int); //函数声明 |
1 | /*例:用递归求n!*/ |
内置函数
同一函数被反复调用的话会在往返过程中消耗大量时空资源,增加调用开销,因此使用内置函数解决
在编译时直接将被调函数的代码嵌入到主调函数中(实参会对原代码中的形参做相应的位置替换),而不做流程的跳转,因此称为内置函数,形式为inline 数据类型 函数名(形参说明){}【一定要注明inline】
虽然节省了运行时间,但增加了目标程序长度,因此仅适用于使用频繁且规模很小的简单声明函数【不含复杂控制语句,如switch,循环,···】
函数重载
C++允许同一个函数名定义多个函数,而这些函数的参数个数和参数类型可以不同,旨在解决函数功能相同但参数类型不同的麻烦;
若只是返回值不同就不构成重载;
重载的形参必须个数不同或类型不同或顺序不同
1 |
|
在使用时,同名函数的功能应该相同或相近,若完全不相关就很影响可读性
函数模板
C++提供函数模板(建立一个通用函数),其函数类型和形参不具体指定而用虚拟类型代表
定义函数模板的一般形式:
1 | template <typename T> |
主要是相较于函数重载,这样用程序更简洁方便,但只适用于函数体相同且函数参数个数相同仅参数类型不同的情况
有默认函数参数
为某个函数设置默认值,则在后续每次调用时避免重复赋值;
如果函数的定义在函数调用之后,需要在函数调用之前有函数声明;那么若在函数声明中给出默认值,则在函数定义时一般不给默认值(否则会报错:重复指定默认值)。
[!WARNING]
一旦某个参数指定了默认值,它右边所有的参数都必须也指定默认值
1 | void f4(float a, int c, int b=0, char d='a'); |
对于同一个函数不能既作为重载函数,又作为有默认参数的函数。
局部变量
作用域仅在所定义的函数或复合语句内,形参就局部变量,只能在函数内部使用;因此在不同函数中可以使用同名的变量以代表不同的对象,互不干扰。
1 | int max( int a, int b) ; //函数声明中出现形参a,b |
全局变量
从定义开始到程序结束始终生效,为程序中所有函数所共用
在局部变量的作用范围内,局部变量优先于全局变量
其作用旨在增加函数间的数据联系
不过因其在整个执行过程中都要占用存储单元,而不是仅在需要时才开辟单元,因此非必要不使用全局变量,否则会导致通用性降低(函数执行时受到外部变量影响),且降低程序的清晰程度
相较于局部变量,全局变量有自己的默认初始值:数值型为0,字符型为’ ‘,布尔型为0
变量的区分
定义:需要建立存储空间,如int a,系统是根据变量的定义去分配存储空间的
声明:不需要建立存储空间,如’extern int a;’(也称外部变量)
1 | int main( ) |
静态变量
用static声明,存储在内存的静态区,具有默认初始值,从程序运行开始直至结束一直占据固定的存储单元
注:“static a;” 是不合法的,应写成 “static int a;”
使用方式:
- 去声明局部变量:本函数调用结束后不释放,在程序执行整个期间始终存在,留作下次继续用,不再初始化恢复初值
- 声明全局变量:则该变量的作用域仅在本文件中生效,对于那种其他文件的
import调用就不管用了
其他变量还有寄存器变量(register),自动变量/动态变量(auto)
内部函数/静态函数
只能用于本文件,函数前用static去做标识
外部函数/动态函数
可跨文件使用,前加’extern’,不过一般省略不写,因为默认都是动态的
要调用其他文件里的函数的话,最好俩放同一项目文件中,并在使用前做好声明
1 | /*这是个文件1,一会有用*/ |
基于这样的思想,设计出了库函数,也就是cmath啥的这样只用#include <cmath>就可在该文件中合法使用各自数学库函数啦
头文件
就是刚才说的用#include指令包含的;是源文件中不可缺少的成分。
主要用于:
对类型的声明(C++新增的,预定义的模板和类)
对函数的声明
#include对内置函数inline的定义
宏定义(
#define定义的符号常量;const声明的常变量)全局变量定义
外部变量定义’extern int a;’
编程时,各函数包含在一个文件中,比如一个文件放主函数(调用其他的#include "T4-3.cpp"),两个文件放被调用的函数,这几个文件放同一个项目(.prj)里

