(1)const的位置

const是C++语言引入的一个关键字,是“不变的”、“常量”的意思。用const定义一个变量,实际上是定义了一个“常变量”(即只读变量)。但是,const的用法远不是这么简单,因为C++中有指针、引用、函数等多种机制,所以和const组合在一起,就会遇到很多实际问题。下面从4个方面总结一下const的用法。

(1)const的位置

const的位置比较灵活。一般说来,除了修饰一个类的成员函数外,const不会出现在一条语句的最后。以下是一个使用const的例子。

1. #include <iostream>

2. 

3. int main()

4. {

5.     int i = 5;

6.     const int v1 = 1;

7.     int const v2 = 2;

8.     const int *p1;

9.     int const *p2;

10.     //以下三条语句都会报编译错误,为什么?

11.     //const *int p3;

12.     //int *const p3 = &v1;

13.     //int *const p3;

14.     int *const p3 = &i;

15.     const int *const p4 = &v1;

16.     int const *const p5 = &v2;

17.     const int &r1 = v1;

18.     int const &r2 = v2;

19.     //以下语句会报编译错误,为什么?

20.     //const &int r3;

21.     //以下语句会报警告,并忽略const

22.     int &const r4 = i;

23.     std::cout<<*p4<<std::endl;

24.     return 0;

25. }

复制代码

程序的输出结果是:1。当然,各位也可以自行考察一下其他变量的值。以上程序演示的是const的位置与它的语义之间的关系。表面上看起来很复杂,但实际上是有规律可循的。也就是说,const和数据类型结合在一起,形成所谓”常类型“,然后利用常类型来声明或定义变量,这样就产生了常变量。const用来修饰类型时,既可以放在类型的前面,也可以放在类型的后面;用常类型声明或定义变量时,const只会出现在变量前面。const和被修饰类型之间不能有其他标识符存在。

在理解有const存在的声明语句时,关键是要搞清楚到底什么是“不可变”的。对一个具体的变量来说,如果const直接出现在该变量的前面,则该变量的值一旦初始化就不能再改变。所以,const int v1;和int const v1;都是合法的,而且是等价的。由于const直接出现在v1前,所以v1是只读变量(常变量)。而int const *p和int *const p则是不同的声明语句,原因是前者的const修饰的是int,而后者的const修饰的是int*。前者是常指针,表示指针p指向的是一个只读的整型量(指针所指单元的内容不允许修改),而指针本身可以指向其他的常变量;而后者是指针常量,表示指针p本身的值不能修改(const直接出现在p的前面),即一旦指针p指向某个整数之后,就不能再指向其他整型量。如果指针被定义为指针常量,那么在定义它的时候必须同时初始化,否则编译器报错。

引用本身可以理解成一个指针常量,所以在引用前使用关键字const没有意义。上例中int &const r4 = i;语句的const是多余的,编译器在给出警告信息后,自动忽略const的存在。常引用是指将被引用对象当做一个常量,也就是不允许通过引用来修改被引用对象的值。常引用有它独特的特点,具体可参阅关于常引用的资料。要清楚的一点是:普通变量可以当做常变量来看待,但反过来不可以。

在很多情况下,为了表达同一种语义,可以将const放在不同的位置,如前面的例子。但在某些情况下,const只能放在特定的位置,否则意义就会完全不一样。下面是一个const配合二重指针的例子。在这个程序中,const的位置是不能随意变动的。

1. #include <iostream>

2. 

3. int main()

4. {

5.     int const **p1;

6.     int *const *p2;

7.     int i = 5;

8.     int j = 6;

9.     const int *ptr1 = &i;

10.     int *const ptr2 = &j;

11.     p1 = &ptr1;

12.     p2 = &ptr2;

13.     std::cout<<**p1<<std::endl;

14.     std::cout<<**p2<<std::endl;

15.     return 0;

16. }

复制代码

程序的运行结果是:

5

6

在程序中定义了两个二重指针p1和p2,它们的声明分别是int const **p1和int *const *p2,但含义完全不同。p1不是指针常量,它所指向的变量类型是int const*(指向整型常量的指针);p2也不是指针常量,但它所指向的变量是指针常量(int* const,即指向整型的指针常量)。所以为p1和p2赋值是有讲究的。如果在上面的程序中,使用这样的赋值p1 = &ptr2或p2 = &ptr1,都会产生编译错误。各位有兴趣的可以自行试验一下,并分析产生错误的原因。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值