C++ Primer 学习笔记(4): 参数传递
2010-03-05 20:04
337 查看
参数传递
参数传递有两种方式,即值传递和引用传递。
按值传递不是在所有的情况下都适合。不适合的情况包括:
(1)当大型的类对象必须作为参数传递时。由于拷贝对象带来的开销会过大。
(2)当实参的值必须被修改时。
1、引用参数
1.1 使用引用参数的场合
(1)必须修改实参的值而避免使用指针的时候。
例如交换两个变量的值:
(2) 向主调函数返回额外的结果,很显而易见。
(3) 向函数传递大型对象。
Tip: 若希望用引用参数以避免拷贝用作实参的大型类对象,同时又希望防止函数修改实参的值。如果引用参数不希望在被调用的函数内部被修改,那么把参数生命为const型的引用是个不错的办法。
int foo (const X& xx){...}
1.2 指针的引用
主要用于要修改指针本身的时候
1.3 引用和指针参数的关系
引用必须被初始化为指向一个对象(不可以用常数作引用参数的实参),一旦初始化了,它就不能再指向其他对象。指针可以指向一系列不同的对象也可以什么都不指向。
一个Matrix对象重载加法运算符实现的例子:
2 数组参数
数组的长度与参数声明无关。下面三个声明是等价的:
问题:传递数组给函数时使其知道它的长度
方法一:提供一个含有数组长度的额外参数,很常用
方法二:将参数声明为数组的引用。当参数是一个数组的类型的引用时,数组长度成为参数和实参类型的一部分,编译器检查数组实参的长度与在函数参数类型中指定的长度是否匹配。
方法三:使用抽象容器类型作为参数, vector<int> vec;
3 函数指针
声明、初始化、调用函数指针:
函数指针的数组:
函数指针作参数:
参数传递有两种方式,即值传递和引用传递。
按值传递不是在所有的情况下都适合。不适合的情况包括:
(1)当大型的类对象必须作为参数传递时。由于拷贝对象带来的开销会过大。
(2)当实参的值必须被修改时。
1、引用参数
1.1 使用引用参数的场合
(1)必须修改实参的值而避免使用指针的时候。
例如交换两个变量的值:
//使用引用参数 void rswap(int &i, int &j) { int temp = j; j = i; i = temp; } //使用指针参数 void swap(int *i, int *j) { int temp = *j; *j = *i; *i = *j; } int main() { int i = 1, j = 2; swap(&i, &j); rswap(i, j); }
(2) 向主调函数返回额外的结果,很显而易见。
(3) 向函数传递大型对象。
Tip: 若希望用引用参数以避免拷贝用作实参的大型类对象,同时又希望防止函数修改实参的值。如果引用参数不希望在被调用的函数内部被修改,那么把参数生命为const型的引用是个不错的办法。
int foo (const X& xx){...}
1.2 指针的引用
主要用于要修改指针本身的时候
//交换指针 void ptrswap( int *&v1, int *&v2) { int *tmp = v2; v2 = v1; v1 = tmp; }
1.3 引用和指针参数的关系
引用必须被初始化为指向一个对象(不可以用常数作引用参数的实参),一旦初始化了,它就不能再指向其他对象。指针可以指向一系列不同的对象也可以什么都不指向。
一个Matrix对象重载加法运算符实现的例子:
//这种方法效率很低,要拷贝很多数据,以及类的初始化等操作 //调用方法 a + b Matrix operator+(Matrix m1, Matrix m2) { Matrix result; //计算结果 return result; } //使用指针来实现 //调用方法 &a + &b //但是三个对象的加法变得很困难 /// &a + &b + &c 错误,因为&a + &b 的返回值是Matrix对象 /// &(&a + &b) + &c 这样可以 /// Matrix operator+( Matrix *m1, Matrix *m2) { Matrix result; //计算result return result; } //使用引用参数实现 //支持 a + b + c Matrix operator+( Matrix &m1, Matrix &m2) { Matrix result; //计算result return result; }
2 数组参数
数组的长度与参数声明无关。下面三个声明是等价的:
//三个等价的putValues()声明 void putValues( int*); void putValues( int[]); void putValues( int[10]);
问题:传递数组给函数时使其知道它的长度
方法一:提供一个含有数组长度的额外参数,很常用
void putValues( int[], int size);
方法二:将参数声明为数组的引用。当参数是一个数组的类型的引用时,数组长度成为参数和实参类型的一部分,编译器检查数组实参的长度与在函数参数类型中指定的长度是否匹配。
//参数为10个int的数组 void putValues( int (&arr)[10] ); int main() { int i, j[2]; putValues( i ); //错误,实参不是一个10个int的数组 putValues( j ); //错误,实参不是一个10个int的数组 return 0; }
方法三:使用抽象容器类型作为参数, vector<int> vec;
3 函数指针
声明、初始化、调用函数指针:
int calc( int , int); int (*pf)(int, int) = 0; //函数指针声明 pf = calc; //初始化 pf(a, b); (*pf)(a, b); //两种调用方式
函数指针的数组:
//函数指针的数组 int( *test[10] )(); typedef int(*PFV) (); PFV test[10];
函数指针作参数:
int sort(string*, string*, int(*)(const string&, const string&)); typedef int(*PFI2S)(const string&, const string&); int sort(string*, string*, PFI2S);
相关文章推荐
- C++ Primer 学习笔记_21_函数 --函数定义、参数传递
- C++ primer学习笔记_6_函数---函数定义、参数传递
- 【C++学习笔记】函数基础和参数传递
- Python学习笔记7-把函数当参数传递、指定可变参数
- Python学习笔记7-把函数当参数传递、指定可变参数
- C#学习笔记:参数传递(详解)
- springmvc学习笔记(7)——传递对象作为参数(POJO)
- Java学习笔记·Servlet互相传递参数简单实例
- [读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析
- spring MVC学习笔记(三) spring MVC视图与controller之间参数传递
- C++函数的参数及其传递方式学习笔记
- air 学习笔记:bat 调用air 传递参数 打包
- 黑马程序员--Java基础学习笔记【参数传递、访问控制符、内部类】
- Python学习笔记(四)-- 函数中的参数传递
- Java学习笔记 --- Java中的参数传递问题
- asp.net 学习笔记 向自定义控件传递参数
- [读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析
- 【菜鸟C++学习笔记】22. 参数的传递机制
- python学习笔记-(13)python中的函数参数传递
- C#.NET学习笔记---C#中方法参数的传递方式: 值类型(默认),ref类型,out类型和params类型