2011-8-30 21:45 周二 阴有中雨
关键字:形参,实参,函数
6.14 使用预处理器进行调试
1 预处理器定义的四种在调试时常用的常量:
__FILE__ 文件名
__LINE__ 当前行号
__TIME__ 文件被编译的时间
__DATE__ 文件被编译的日期
2 assert 断言预处理宏,定义在cassert.h头文件中,使用时要包含这个头文件。
7.1 函数的定义
7.1.1 函数的返回类型
1 函数的返回类型可以是内置类型、类类型、复合类型(如指针类型)、void类型。
2 函数不能返回另一个函数或者内置数组类型,可以返回指向函数的指针或指向数据元素的指针的指针。
7.2 参数传递
7.2.1 非引用形参
1 形参的初始化与变量的初始化一样:如果形参具有非引用类型,则复制实参的值;如果形参为引用类型,则它只是实参的别名。
2普通的非引用类型的参数通过复制对应的实参来初始化。由于是用的实参的副本来初始化形参的,所以函数并没有访问调用所传递的实参本身,也不会修改实参的值。
3 非引用实参仅表示对应实参的局部副本。对这类形参的修改仅仅是改变了局部副本的值。一旦函数执行结束,这些局部变量的值也就不会存在了。
4 指针引参
指针引参在函数内部不会改变指针实参传递形参之前所指向的对象,但可以改变其所指向对象的值。
int b = 20;
void reset(int *ip)
{
*ip = 0;
int a = 20;
ip = &b;
}
void main( void)
{
int i = 42;
int *p = &i;
cout<< " i = " << i<<endl;
cout<< " *p = "<< *p<<endl;
cout<<" p = "<< p<<endl;
reset(p);
cout<<" =========== "<<endl;
cout<< " i = " << i<<endl;
cout<< " *p = "<< *p<<endl;
cout<<" p = "<< p<<endl;
}
实际输出:
i = 42
*p = 42
p = 0012FF60
===========
i = 0
*p = 0
p = 0012FF60
5 const形参
如果函数使用非引用的非const形参,则可给该函数传递const和非const的实参。这里因为初始化复制了初始化的值,它只是复制,只是一个副本。
如果是const类型的形参。由于实参仍然是以副本的形式传递,因此仍然可以使用const对象或非const对象来传递实参,但此时在函数内部不能改变实参的这个局部副本,因为在函数内部,这个形参是个const对象。
6 复制实参的局限性
不适合复制实参的情况:
1) 当需要在函数中修改实参的值时。
2) 当需要以大型对象作为实参传递时。对实际的应用而言,这时需要占用大量的时间和存储空间。
3) 无法实现对象的复制时。
7.2.2 引用形参
1 const引用避免实参的复制和修改。
2 非const引用形参,只能与完全同类型的非const对象关联。
3 应该将不需要修改相应实参的形参定义为const引用。
4 int *&v1 从右到左理解:v1是一个引用,与指向int类型对象的指针相关联。当用这样的形式做形参时,传递到函数内部的只是一个指针的别名。
5 一般不用容器作为函数的形参。
7.2.4 数组形参
1 可以将函数的数组形参写成数组的形式,但都是ini *类型的。
2 写成数组的形式,形参的长度会引起误解。程序编译时,不会检查数组形参中的数组形参长度,若想传递长度,只能显示传递给函数长度或者传递给函数数组的第一个和最后一个元素的下一个位置的指针。。
3 通过引用传递数组。
形式: void printValues( int (&arr)[10] );
此时编译器会检查数组实参的大小与形参的大小是否匹配。