留下足迹,他日来详细解。
今天看下Primer,发表下const限定符和指针及参数传递方面的见解。
一.指向Const对象的指针
常见定义 const int *p; //p is a referrence to conts int
指向const对象的指针与const指针是有明显区别的,const指针必须在定义时对其初始化,而前者则没有要求。指向const对象的指针有以下特性:
1>。不允许通过指针来改变其所指的const值,同时为了保证这个特性,C++强烈要求指向const对象的指针也必须具有const特性。
eg: const double *cptr;
*cptr=42; //error cptr maybe const
从错误提示中可了解cptr指向的可能为const对象,即不可改变的值。
常见错误:
1.把一个const对象的地址赋给一个普通的,非const对象的指针也会导致编译错误
(因为非const对象的指针可通过指针修改指针指向的值,与const对象相悖).
2.不能使用 void*指针保存const对象的地址,而必须使用const void*类型的指针保存。
///////////////////
但可以把非const对象的地址赋给指向const对象的地址,但不允许通过指针方式修改对象的值,可通过别的方式修改。
二。const指针
定义 int *const p=&xx;
首先必须初始化,本身的值不能修改,也不能被赋值,但是可以通过指针修改所指对象的值
三。指向const对象的const指针
定义
const double *const pi=&xx;
四.指针和typedef
typedef string *pstring;
const pstring cstr;
以上两句 与 string *const cstr等价;
typedef string *pstring; //pstring是一个指向string的指针
const pstring cstr; //对指针修饰const
五.参数传递
1.非引用形参
int gcd(int v1,int v2) ;
普通的非引用类型的参数通过复制对应的实参实现初始化,当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值
2.指针形参
int max(int *x,int *y);
函数的形参也可以是指针,此时将复制实参指针,与其他非引用类型的形参一样,该类形参的任何改变也仅作用于局部副本,如果函数将新指针赋给形参,主调函数使用的实参的值没有改变。
注意事实上复制的指针只影响对指针的复制,如果函数形参是非const类型的指针,则函数可通过指针实现复制,修改指针所指向对象的值。也就是说地址没有变,变的是地址所指向的值。
这里有个例子:
#include<iostream>
using namespace std;
void swap(int *x,int *y);
void swap(int *x,int *y)
{
int *temp;
temp=x;x=y;y=temp;
}
int main()
{
int x,y;
cin>>x>>y;
swap(&x,&y);
cout<<x<<" "<<y<<endl;
system("pause");
return 0;
}
如果交换的是指针的值,因为传递的是副本,所谓x.y的值并没有发生改变,但变成这样,
#include<iostream>
using namespace std;
void swap(int *x,int *y);
void swap(int *x,int *y)
{
int temp;
temp=*x;*x=*y;*y=temp;
}
int main()
{
int x,y;
cin>>x>>y;
swap(&x,&y);
cout<<x<<" "<<y<<endl;
system("pause");
return 0;
}
交换指针指向的值,则x.y的值互换。变量也是地址的一种名字,地址没有,但地址的值变了。
3.引用形参
可以使用引用形参返回更多额外的信息
利用const引用避免复制 因为形参是引用,所以不复制实参,又因为形参是const引用,所以函数不能使用引用来修改实参
4,更灵活的指向const的引用
如果函数具有普通的非const引用形参,则显然不能通过const对象进行调用,毕竟,此时函数可以修改传递进来的对象,这样就违背了实参的特性,但比较容易忽略的是,调用这样的函数时,传递一个右值或需要转换的类型的对象同样是不允许的,
关键在于 非const的引用形参只能与完全同类型的非const对象关联
所以应该将不修改相应实参的形参定义为const引用
eg; string::size_type find_char(string &s,char c)
{
/*.....................*/
}
当调用这个函数时find_char("hello world",'0') 会发生错误,不能通过字符串字面值来调用这个函数
所以一般情况下 应该将不需要修改的引用形参定义为const引用,普通的非const引用形参在使用时不太灵活,这样的形参既不能用const对象初始化也不能用字面值或产生右值的表达式实参初始化。
5.传递指向指针的引用