const和指针

const和指针有如下三种组合,不同的组合其代表的含义不同:

1、const int * p1=&x; (或者写成int const * p1=&x;)
2、int * const p2=&x;
3、const int *const p3=&x;

一、const int * p1=&x;

1、指向整形变量(或常量)的指针;
2、不能通过*p1修改值;
3、x可以是常量也可以是变量,如果是变量则可以通过x=xx进行值的修改,否则也不能修改值;
4、可以为p1重新赋值,即改变p1的指向,如p1=&y。

int a=10;
const int b=12;

const int *p1=&a;//p1指向的是变量   对应描述3
const int *p2=&b;//p2指向的是常量   对应描述3

cout<<*p1<<endl;
cout<<*p2<<endl;

*p1=20;//异常,不能通过*p修改值   对应上述第2条描述
cout<<*p1<<endl;

a=20;//因为a是变量,因此可以修改a的值   对应描述3
cout<<*p1<<endl;
b=22;//异常,因为a是常量,因此不能修改b的值   对应描述3
cout<<*p2<<endl;

p1=&b;//可以为p1重新赋值,即改变p1的指向    对应描述4  
cout<<*p1<<endl;

二、int * const p2=&x;

1、是一个指向整形变量(不能是常量)的常量指针,其指向的x一定是一个变量,如果是常量编译器会报错;
2、能通过*p2修改值;
3、因为x是变量,因此可以通过x修改值;
4、不能为p2重新赋值,即这种类型的指针在初始化后不能再次为其修改指向。

int a=10;
const int b=12;

int * const p1=&a;
int * const p2=&b;//异常,常量指针指向的对象必须是变量  对应描述1
*p1=20;//通过*p1修改值   对应描述2
cout<<*p1<<endl;

a=22;//因为a是变量,因此可以通过a修改值;  对应描述3
cout<<*p1<<endl;

int c=55;
p1=&c;//异常,不能为p2重新赋值,即在初始化后不能再次为其修改指向
cout<<*p1<<endl;

三、const int *const p3=&x;
1、指向整形常量(或变量) 的常量指针
2、p3是一个常量,因此不能通过*p3修改值;
3、这里的x可以是常量,也可以是变量,如果为常量则不能修改x的值;
4、p3因为是常量,因此不能在初始化后再次为其修改指向。

int a=10;
const int b=12;

const int * const p1=&a;//a是变量   对应描述3
const int * const p2=&b;//b是常量   对应描述3

*p1=20;//异常,不能通过*p1修改值    对应描述2
cout<<*p1<<endl;
*p2=20;//异常,不能通过*p1修改值    对应描述2
cout<<*p2<<endl;

const int c=55;
p1=&c;//异常,不能为p1重新赋值以改变其指向   对应描述2
p2=&c;//异常,不能为p2重新赋值以改变其指向   对应描述2

四、const与函数形参

在程序设计中我们会经常调用函数,调用函数就会涉及参数的问题,那么在形参列表中const形参与非const形参对传递过来的实参有什么要求呢?
先来看一个简单的例子:

void print_str(const string s)  
{  
      cout<<s<<endl;  
}  
int main()  
{     
      print_str("hello world");  
      return 0;  
}  

毫无疑问,const实参传递给const形参,正确调用函数,如果你将第4行代码中的const去掉,也能得到正确的结果。
但是:如果形参为引用或者指针类型时,程序是否正常呢?

void print_str( char * s)
{
      cout<<s<<endl;
}

void print_str1(string & s)
{
      cout<<s<<endl;
}

int main()
{

    const char * a="hello world";
    print_str(a);//编译错误,但是如果void print_str(const char * s),则正常运行
    print_str1("hello world");//编译报错,但如果void print_str1(const string & s),则正常运行

    return 0;
}     

普通形参加不加const限定符对实参没有影响,引用形参和指针形参前面没有const限定符时,实参必须是非const的,而前面有const限定符时对实参也没有什么影响。上述代码中,指针a是一个const变量,而print_str1(“hello world”);中的hello world 会被编译器编译成const 类型,因此调用函数时都会编译错误。

为什么会出现这种情况?

原因在于实参的传递方式不同,如果是普通形参,函数只是操纵的实参的副本,而无法去修改实参,因此实参是不是const就没关系。如果形参是引用或者指针就不同了,函数对形参的操作就是对实参操作,因此函数形参和实参必须在类型(这里主要是指是否是const修饰)上能相互转化。

猜你喜欢

转载自blog.csdn.net/zhaocuit/article/details/75269362