C++学习笔记(二)——const限定符

C++学习笔记(二)——const限定符

一、const限定符

  • (1)const对象必须初始化

    const int k;//k是一个未经初始化的变量
    
  • (2)const的引用
    与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象;

    const int c1 = 10;
    const int &r1 = c1; // 不能修改r1绑定的对象
    r1 = 42; //错误 不能修改它绑定的对象
    int &r2 = c1;
    

    对const的引用简称为“常量引用”

  • (3)对const的引用

    const int &r1 = 42 //正确,r1是一个常量引用 
    //区别于 
    int &r2 = 42;//这是错误的
    
  • (4)不同类型常量引用的的过程

    double dval = 3.14;
    const int &ri = dval;
    内部转换过程如下:
    const int temp = dval; //浮点转换成int类型
    const int &ri = temp;
    

    当绑定到不同的变量上时,此时绑定的对象是临时量(temp)而不是dval;
    所以上面的属于非法操作。

    明白了这一点,通过代码可以发现:

    double dval = 3.14;
    const int &a = dval;  //warning C4244: “初始化”: 从“double”转换到“const int”,可能丢失数据
    cout << a << endl;  // 因为a绑定的是temp,temp是3
    
    dval = 2;  // 修改dval为2
    cout << a << endl; // a的输出还是3,因为绑定的是temp为3,所以a的值不变
    

    a和dval并不绑定, a绑定的只是内部的临时变量temp而已,所以通过修噶爱dval来改变自以为绑定的a是不可能的。

  • (5)相同类型常量引用
    相同类型的常量引用和常量之间,常量引用可以绑定到相同类型的常量
    如下面的代码 常量引用a常量val
    a绑定到val是合法操作,不允许通过a修改val的值,但是可以通过修改val的值修改a;

    int val = 3;
    const int &a = val;
    cout << a << endl; // a =3
    
    val = 2; 
    cout << a << endl; // a = 2;
    
    a = 4; //error C3892: “a”: 不能给常量赋值
    cout << a << endl;
    

二、指针和const

  • (1)指向常量的指针
    普通的指针不能指向常量 int * => const int (x)
    常量的指针可以指向一个常量 const int * => const int (√)

    /*指向常量的指针如下:*/
    const double pi = 3.14;
    
    double *ptr = &pi // 错误 普通的指针不能指向常量
    
    const double *cptr = &pi; //正确 常量的指针可以指向一个常量 
    *cptr = 5; //错误 不能给*cptr赋值
    

    且不能修改*cptr。

  • (2)常量的指针指向非常量对象
    上一节指针中我们知道指针不能指向不同类型的对象
    有两个例外:
    一个就是:允许指向常量的指针指向一个非常量对象
    即:

    double dval = 4.14;//定义一个非常量对象
    cptr = &dval;
    
    cout << *cptr << dval << endl;// cptr是一个指向常量的指针他最终指向一个非常量对象
    
    dval = 5.14;
    cout << *cptr << dval << endl;
    
    *cptr = 6.14; //error C3892: “cptr”: 不能给常量赋值
    cout << *cptr << dval << endl;
    

    不能通过修改 *cptr 来改变因为它是一个const类型
    但可以通过修改dval 来改变 *cptr的值。和 一、中的(5)常量的引用类似

  • (3)const指针(int errNumb = 0; int *const a = &errNumb;)
    const指针分为两种:
    (1)常量指针
    (2)指向常量的常量指针


指针是对象而引用不是,因此就像对其他对象类型一样
允许把指针本身定为常量,常量指针必须初始化
*const的含义是 不变的是指针本身的值,而并非指向的那个值。
PS:
指针是常量,并不意味着不能通过指针修改其所指对象的值,取决于对象的类型
如下两种情形:

int errNumb = 0;
int *const curErr = &errNumb;
const double pi = 3.14159;
const double *const pip = &pi;1)通过指针修改其所指对象的值
*curErr = 5; //通过指针,修改所指对象的值
cout << errNumb << endl;2)不能通过指针修改其所指对象的值
*pip = 2.72; // error C3892: “pip”: 不能给常量赋值
cout << pip << endl;

(1)相当于我的curErr的地址指向不变(即地址不能改变),但不代表不能通过指针来修改值
(即地址里面的值可以改变)

(2)pip是指向常量的常量指针代表地址的指向不允许改变,并且地址里面的值也不允许改变。所以不论是pip所指向的对象值还是pip自己存储的那个地址都不能改变。

三、顶层const和底层const

顶层const:一个指针本身添加const限定符就是顶层const(*const)
底层const:指针所指的对象(*p)添加const就是底层const( const *p)

区别:底层的const不能赋值给非常量的底层const。


因为针对 指针 添加const修饰符只有两种情形:(他们的地址指向都不变)
(1)指向常量的指针(可以不初始化)
不能改变其指向内容的指针(地址),地址里面的值可以改变,地址不可以改变。

// 底层const
const int *p; 
int const *p;  

这两个都一样。

(2)常量指针(必须初始化)
地址里面的值不可以改变

// 顶层const
const int  *const p;
int const  *const p;

这两个都一样。


区分各种类型:

1. const int p; // p is a int const. p是一个int型常量 这个很简单

2. const int *p; //p is a point to int const. p是一个指针,指向int型常量。即p是一个指向int型常量的指针。

3. int const *p; //与2相同 const int 和 int const 是一样的意思。《C++ primer》中采用第一种写法。

4. int * const p; // p is a const point to int. p是一个指向int的const指针

5. const int * const p; //p is a const point to int const. p是一个指向int型常量的const指针。

6. int const * const p; //同5
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值