C++内部函数和外部函数
函数本质上是全局的,因为一个函数要被另外的函数调用,但是,也可以指定函数只能被本文件调用,而不能被其他文件调用。根据函数能否被其他源文件调用,将函数区分为内部函数和外部函数。
内部函数
如果一个函数只能被本文件中其他函数所调用,它称为内部函数。在定义内部函数时,在函数名和函数类型的前面加static。函数首部的一般格式为:
1
|
static 类型标识符 函数名(形参表);
|
如
1
|
static int fun( int a, int b);
|
内部函数又称静态(static)函数。使用内部函数,可以使函数只局限于所在文件。如果在不同的文件中有同名的内部函数,互不干扰。通常把只能由同一文件使用的函数和外部变量放在一个文件中,在它们前面都冠以static使之局部化,其他文件不能引用。
外部函数
在定义函数时,如果在函数首部的最左端冠以关键字extern,则表示此函数是外部函数,可供其他文件调用。如函数首部可以写为:
1
|
extern int fun ( int a, int b);
|
这样,函数fun就可以为其他文件调用。如果在定义函数时省略extern,则默认为外部函数。本教程前面所用的函数都是外部函数。
在需要调用此函数的文件中,用extern声明所用的函数是外部函数。
【例】输入两个整数,要求输出其中的大者,用外部函数实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/*******file1.cpp(文件1)*******/
#include <iostream>
using namespace std;
int main( )
{
extern int max( int , int ); //声明在本函数中将要调用在其他文件中定义的max函数
int a,b;
cin>>a>>b;
cout<<max(a,b)<<endl;
return 0;
}
/*******file2.cpp(文件2)*******/
int max( int x, int y)
{
int z;
z=x>y?x:y;
return z;
}
|
运行情况如下:
1
2
|
7 -34↙
7
|
在计算机上运行一个含多文件的程序时,需要建立一个项目文件(project file),在该项目文件中包含程序的各个文件。详细情况请查看:VC6.0使用教程。
通过此例可知:使用extern声明就能够在一个文件中调用其他文件中定义的函数,或者说把该函数的作用域扩展到本文件。extern声明的形式就是在函数原型基础上加关键字extern。由于函数在本质上是外部的,在程序中经常要调用其他文件中的外部函数,为方便编程,C++允许在声明函数时省写extern。例4.15程序main函数中的函数声明可写成:
1
|
int max( int , int );
|
这就是我们多次用过的函数原型。由此可以进一步理解函数原型的作用。用函数原型能够把函数的作用域扩展到定义该函数的文件之外(不必使用extern)。只要在使用该函数的每一个文件中包含该函数的函数原型即可。函数原型通知编译系统:该函数在本文件中稍后定义,或在另一文件中定义。
利用函数原型扩展函数作用域最常见的例子是#include命令的应用。在#include命令所指定的头文件中包含有调用库函数时所需的信息。例如,在程序中需要调用sin函数,但三角函数并不是由用户在本文件中定义的,而是存放在数学函数库中的。按以上的介绍,必须在本文件中写出sin函数的原型,否则无法调用sin函数。sin函数的原型是:
1
|
double sin ( double x);
|
本来应该由程序设计者在调用库函数时先从手册中查出所用的库函数的原型,并在程序中一一写出来,但这显然是麻烦而困难的。为减少程序设计者的困难,在头文件cmath中包括了所有数学函数的原型和其他有关信息,用户只需用以下#include命令:
1
|
#include <cmath>
|
即可。这时,在该文件中就能合法地调用各数学库函数了。
C++宏定义#define
可以用#define命令将一个指定的标识符(即宏名)来代表一个字符串。定义宏的作用一般是用一个短的名字代表一个长的字符串。它的一般形式为:
1
|
#define 标识符 字符串
|
这就是已经介绍过的定义符号常量。如:
1
|
#define PI 3.1415926
|
还可以用#define命令定义带参数的宏定义。其定义的一般形式为:
1
|
#define 宏名(参数表) 字符串
|
如:
1
|
#define S(a, b) a*b //定义宏S(矩形面积),a、b为宏的参数
|
使用的形式如下:
1
|
area=S(3, 2);
|
用3、2分别代替宏定义中的形式参数a和b,即用3*2代替S(3, 2)。因此赋值语句展开为:
1
|
area=3*2;
|
由于C++增加了内置函数(inline),比用带参数的宏定义更方便,因此在C++中基本上已不再用#define命令定义宏了,主要用于条件编译中。