标签:
重点:
1.每次调用函数时都会重新创建它的形参,并用传入的实参对形参进行初始化。
NOTE: 形参初始化的机理与变量初始化一样。
2.形参的类型决定了形参和实参交互的方式。
(引用->绑定,非引用->拷贝)
3.实参分为:被引用传递(引用形参是实参的别名),被值传递(实参形参是两个相互独立的对象)。
4.传值参数:函数对形参做的所有操作都不会影响实参。
5.指针形参:指针的行为和其他非引用类型一样,当执行指针拷贝操作时,拷贝的是指针的值。拷贝后,两个指针是不同的指针。
NOTE: C程序员常常用指针类型的形参访问函数外部的对象,C++当中,建议使用引用类型的形参代替指针。
6.对于引用的操作实际上是作用在引用所引的对象上。
7.有的类类型不支持拷贝操作,函数只能通过引用形参访问该类型的对象。
8.如果函数无须改变引用形参的值,最好将其声明为常量引用。
例如:编写一个函数比较两个string对象的长度,因为string对象可能会非常长,所以应该尽量避免直接拷贝它们。而比较长度无须改变string对象的内容,所以把形参定义为对常量的引用。
//比较两个string对象的长度
Bool isShorter(const string &s1,const strig &s2)
{
return s1.size()<s2.size();
}
Note:如果函数无须改变引用参数的值,最好将其声明为常量引用。
9.使用形参返回额外信息。
10.当用实参初始化形参会忽略掉顶层const。换句话说:当形参有顶层const时,传给它常量对象或者非常量对象都是可以的。
void fcn(const int i){/*fcn能够读取i,但是不可以修改i*/}
void fcn(int i ){ // 错误:重复定义了fcn(int i)}
11.C++允许具有相同名字的函数,不过前提是不同函数的形参列表有明显区别,而顶层const被忽略掉了,所以有没有顶层const是一样的。
12.可以使用非常量初始化一个底层const对象,但是反过来不行!
int i = 42;
Const int *cp = &i; //正确,但是cp不能改变i;
Int *p = cp; //错误,类型不匹配;
Const int &r = i; //正确,但是r不能改变i;
Int &r3 = r; //错误,类型不匹配;
Const int &r2 = 42; // 正确;
Int &r4 = 42; //错误,不能用字面值初始化一个非常量引用;
13.①要想调用引用版本的reset(reset(i)),只能使用int类型的对象。不能使用字面值,求值结果为int的表达式,需要转换的对象,或者const int类型对象。
②想调用指针版本的reset(reset(&i))只能使用int*。
14.尽量使用常量引用:?普通引用函数可以修改它的实参的值;
?普通引用极大地限制了函数所能接受的实参类型。
(例如整型只能int,不可以const对象,字面值,需要类型转换的对象)
15.数组的两个特性:
⑴不允许拷贝数组;
(因此,无法以值传递的方式使用数组参数)
⑵使用数组会将其转换成指针;
(因此当向函数传递一个数组时,实际上传递的是指向数组首元素的指针)
16.尽管不能以值传递的方式传递数组,但是我们可以把形参写成类似数组的形式:(以下三种形式等价)
Void print ( const int* );
Void print ( const int[ ]);
Void print ( const int[10]);
17.管理指针形参:
①使用标记指定数组长度;
//要求数组本身含有一个结束标记;
Void print ( const char *cp )
{
If(cp) //指针不是空指针
While(*cp) //指针所指的字符不是空字符
Cout << *cp << endl;
}
②使用标准库规范;
//传递指向数组首元素和尾后元素的指针;
Void print ( const int *beg, const int *end )
{
//输出beg和end之间(不含end)所有元素;
While( beg != end )
Cout << *beg++ << endl;
}
③显示传递一个表示数组大小的形参;
Void print ( const int ia [ ],size_t size)
{
For( size_t int i=0 ; i != size ; i++ )
{
Cout << ia[i] << endl;
}
}
/* 三个print函数都把数组形参定义成了指向const的指针,只有当函数确实要改变元素值的时候,才能把形参定义成指向非常量的指针*/
18.数组引用形参:
&arr两端的括号不可少
F ( int &arr[10] ) //错误:将arr声明成了引用的数组;
F ( int (&arr)[10] ) //正确:arr是具有10个整数的整型数组的引用
19.所谓的多维数组就是数组的数组。
20.多维数组传递给函数,真正传递的是指向数组首元素的指针。因为是数组的数组,所以首元素本身就是一个数组,指针就是一个指向数组的指针
Void print ( int (*matrix)[10] , int rowsize );
Void print ( int matrix[][10] , int rowsize );
size _t 为了增强程序的可移植性,便有了size_t ,不同系统上,定义size_t可能不一样。
经测试发现,在32位系统中size_t是4字节的,在64位系统中,size_t是8字节的,这样利用该类型可以增加程序移植性。
size_t的定义
它的定义在/usr/include/linux/types.h
typedef _kernel_size_t size_t;
21.main:处理命令行选项
Int main(int argc,char *argv[ ]) { ... }
Argc:表示数组中字符串的数量,argv是一个数组,它的元素是指向C风格字符串的指针。SO:等价于
Int main(int argc,char **argv) { ... }
Note:使用argv中的实参时,一定要记得可选的实参从argv[1]开始;argv[0]保存程序的名字,而非用户输入。
22.处理不同数量实参的函数:
①如果所有的实参类型相同,可以传递一个名为initializer_list的标准库类型;
②如果实参的类型不同,我们可以编写一种特殊的函数,也就是所谓的可变参数模板。
23.initializer_list是一种模板类型,类似于vector:
Initializer_list<string> ls;//initializer_list的元素类型为string
Initializer_list<int> li;//initializer_list的元素类型为int
(和vector不同的是,initializer_list对象的元素永远是常量值,不可改变。)
参数传递:传值参数,指针形参,传引用参数,const形参和实参,数组形参,main:处理命令行选项,含有可变形参的函数
标签:
原文地址:http://www.cnblogs.com/YH-shjd-senvn/p/5775232.html