您的位置:首页 > 编程语言 > C语言/C++

[C++]函数与编译预处理(二)

2016-11-28 23:38 302 查看
函数与编译预处理
参数个数可变的函数
到目前为止,在定义函数时,都明确规定了函数的参数个数及类型。在调用函数时,实参的个数必须与形参相同。在调用具有缺省参数值的函数时,本质上,实参的个数与形参的个数仍是相同的,由于参数具有缺省值,因此,在调用时可省略。在某些应用中,在定义函数时,并不能确定函数的参数个数,参数的个数在调时才能确定。在C++中允许定义参数个数可变的函数。


首先,必须包含头文件“stdarg.h”,因为要用到里面的三个库函数 va_start( )、va_arg( )和va_end( )。
其次,要说明一个va_list类型的变量。va_list与int,float类同,它是C++系统预定义的一个数据类型(非float),只有通过这种类型的变量才能从实际参数表中取出可变有参数。如:va_list ap;
va_start(ap,b):初始化
va_arg(ap,int):依次取参数
va_end(ap):正确结束

va_start():有两个参数,va_start(ap,b); b即为可变参数前的最后一个确定的参数。
va_arg():有两个参数,va_arg(ap,int) int即为可变参数的数据类型名。
int temp;
temp=va_arg(ap,int);
va_end():完成收尾工作。va_end(ap);
在调用参数个数可变的函数时,必定有一个参数指明可变参数的个数或总的实参个数。如第一个参数值为总的实际参数的个数。

使用参数数目可变的函数时要注意以下几点:
1、在定义函数时,固定参数部分必须放在参数表的前面,可变参数在后面,并用省略号“...”表示可变参数。在函数调用时,可以没有可变的参数。
2、必须使用函数va_start()来初始化可变参数,为取第一个可变的参数作好准备工作;使用函数va_arg()依次取各个可变的参数值;最后用函数va_end()做好结束工作,以便能正确地返回。
3、在调用参数个数可变的函数时,必定有一个参数指明可变参数的个数或总的实参个数。
函数的重载
所谓函数的重载是指完成不同功能的函数可以具有相同的函数名。

C++的编译器是根据函数的实参来确定应该调用哪一个函数的。

1、定义的重载函数必须具有不同的参数个数,或不同的参数类型。只有这样编译系统才有可能根据不同的参数去调用不同的重载函数。
2、仅返回值不同时,不能定义为重载函数。即仅函数的类型不同,不能定义为重载函数


编译预处理

高级语言编译过程



C语言提供的编译预处理的功能有以下三种:
宏定义 文件包含 条件编译

宏定义
不带参数的宏定义
用一个指定的标识符(即名字)来代表一个字符串,以后凡在程序中碰到这个标识符的地方都用字符串来代替。
这个标识符称为宏名,编译前的替代过程称为“宏展开”。
# define 标识符 字符串
#define PRICE 30
void main(void)
{ int num, total; /*定义变量*/
num=10; /*变量赋值*/
total=num*PRICE;
cout<<"total=“<<total<<endl;
}
编译程序将宏定义的内容认为是字符串,没有任何实际的物理意义。
注意:
1、宏展开只是一个简单的“物理”替换,不做语法检查,不是一个语句,其后不加分号“;”
2、#define命令出现在函数的外面,其有效范围为定义处至本源文件结束。可以用# undef命令终止宏定义的作用域。
#define G 9.8
void main(void )
{.....}
# undef G
int max(int a,int b)
{...... }
3、对程序中用双引号括起来的字符串内容,即使与宏名相同,也不进行置换。
4、在进行宏定义中,可以用已定义的宏名,进行层层置换。

带参数的宏定义



按#define命令行中指定的字符串从左至右进行置换宏名,字符串中的形参以相应的实参代替,字符串中的非形参字符保持不变。

定义宏时在宏名与带参数的括弧间不能有空格。
#define S_ (r) P*r*r
带参数的宏与函数调用的区别
相同:有实参、形参,代入调用。
不同之处
1、函数调用先求表达式的值,然后代入形参,而宏只是机械替换。
2、函数调用时形参、实参进行类型定义,而宏不需要,只是作为字符串替代。
3、函数调用是在运行程序时进行的,其目标代码短,但程序执行时间长。而宏调用是在编译之前完成的,运行时已将代码替换进程序中,目标代码长,执行时间稍快。
一般用宏表示实时的、短小的表达式。

文件包含
一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中。
# include “文件名”



注意:
1、文件名是C的源文件名,是文本文件,后缀名可以任选。*.cpp *.h
2、一个#include语句只能指定一个被包含文件。
3、文件名用双引号或尖括号括起来。
4、包含后所有源文件编译为一个可执行文件。

条件编译
C语言允许有选择地对程序的某一部分进行编译。也就是对一部分源程序指定编译条件。



条件编译有以下几种形式:
1、 # ifdef 标识符
程序段1
# else
程序段2
# end if
当标识符已被定义过(用#define定义),则对程序段1进行编译,否则编译程序段2.
2、 # ifndef 标识符
程序段1
# else
程序段2
# endif
与形式1相反,当标识符没有被定义过(用#define定义),则对程序段1进行编译,否则编译程序段2。
3、 # if 表达式
程序段1
# else
程序段2
# endif
当表达式为真(非零),编译程序段1,表达式为零,编译程序段2。

程序的多文件组织

而在设计一个功能复杂的大程序时,为了便于程序的设计和调试,通常将程序分成若干个模块,把实现一个模块的程序或数据放在一个文件中。当一个完整的程序被存放在多于一个文件中时,称为程序的多文件组织。


内部函数和外部函数
内部函数:函数只限于在本文件中调用,其它文件不能调用,用static 定义该函数。
static float fac( int n)
{ ...... }
外部函数:函数的默认形式,可以被其它文件调用,用extern 定义该函数。调用时,在文件中用extern 说明。
void main(void)
{ extern enter_string( );
char str[80];
enter_string(str);
..........
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 C++