一口气搞懂指针、引用和const的混合

目录

1、普通const变量

2、指针和const的混合(3种情形)

3、普通引用

4、引用和const的混合

5、指针和引用混合

6、指针、引用、const的混合


1、普通const变量

定义时必需赋初始值(可以是宏、数值、常量名),且后期不能被改变。这里const int和int const是一样的。

#include<iostream>
using namespace std;
#define N 10
int main()
{
    const int a = 1;
    int const b = a;
    const int c = N;
    
    system("pause");
    return 0;
}

2、指针和const的混合(3种情形)

#include<iostream>
using namespace std;
int main()
{
    int a = 1;
    int b = 2;
    int* p = &a;  // 普通指针
    
    // 情形1
    /* 指针i、j指向可以改变,但是不能通过*i或*j来改变所指向对象的值 */
    const int * i = &a;
    int const * j = &a;
    i = &b;  // 可以改变i的值
    j = &b;  // 可以改变j的值
    
    // 情形2
    /* 指针k是常指针,可以通过*k改变所指向地址的值,但不能改变k的值 */
    int * const k = &a;
    *k = 9;  // 可以通过*k改变a的值
    cout << a << endl;  // 输出9

    // 情形3
    /* 下面的m、n指针,既不能改变指针的指向,也不能通过*m、*n改变所指对象的值;
        定义时必须初始化,且只能用定义好之后的指针所指对象的值,不能改。
        右边可以是对普通变量取地址 或 对const变量取地址,也可以是普通指针 或 const指针   
    */
    const int * const m = &a;
    int const * const n = &b;


    system("pause");
    return 0;
}

这里有一个技巧,const在指针右边,说明const限制k,k是常量,如果在指针左边,说明是另一种情况 ---- 即,不能通过指针修改被指对象。

还需要注意,如果原变量是const的,指向它的指针也得是const的,如下:

#include<iostream>
using namespace std;
int main()
{
    const int a = 1;     // const类型
    const int * x = &a;  // 指向它的指针也必须是const
    int const * y = &a;  // 也可以这样写

    system("pause");
    return 0;
}

3、普通引用

记住,引用有个特点,定义时必需赋初始值。且定义之后,就没法改变绑定引用到的对象。

#include<iostream>
using namespace std;
int main()
{
    int a = 1;
    int &m = a;  // 引用定义时就必须初始化,且后期不能更改引用对象,下面有例子
    m = 2;       // 通过引用改变被引用的对象的值
    cout << a << " " << m << endl;  // 输出2 2,说明被引用的对象a被改变 
    
    // 例子
    /* 下面说明了引用赋值后,不能再次改变所绑定到的对象 */
    int b = 5;
    m = b;  // 这里,m并未改变绑定对象,而是改变绑定对象a的值为b,即5
    cout << m << " " << a << " " << b << endl;  // 输出5 5 5

    m = 15; // 再次改变绑定对象a的值,并不会对b有任何影响

    // 下面输出15 15 5,b的值没有变,说明m = b那条语句不是改变绑定对象
    cout << m << " " << a << " " << b << endl;  


    system("pause");
    return 0;
}

还需要注意,如果原变量是const的,它的引用也得const的,如下:

#include<iostream>
using namespace std;
int main()
{
    const int a = 1;    // const类型
    const int & x = a;  // 引用也必须是const
    int const & y = a;  // 也可以这样写

    system("pause");
    return 0;
}

4、引用和const的混合

#include<iostream>
using namespace std;
int main()
{
    int a = 1;
    int b = 2;
    /* 不能通过i、j改变所引用的对象a、b的值 */
    const int &i = a;
    int const &j = a;
    
    /* 下面是会报错的 */
    i = 5;  
    j = 5;
    
    system("pause");
    return 0;
}

5、指针和引用混合

#include<iostream>
using namespace std;
int main()
{
    int a = 1;
    int b = 2;
    int *pa = &a;
    int *pb = &b;

    int* &m = pa;  // 普通指针引用
    *m = 5;        // 通过改变指针的引用改变a的值
    cout << a << " " << *pa << " " << *m << endl;  // 输出5 5 5

    m = pb;        // 注意,这里并未改变引用m的绑定对象pa,它只是把pa的值变成了pb
    cout << *pa << endl;  // 输出为b的值-2,说明引用并不能被改变绑定对象

    system("pause");
    return 0;
}

6、指针、引用、const的混合

#include<iostream>
using namespace std;

int main()
{
    int a = 1;
    int b = 2;
    int *pa = &a;
    int *pb = &b;
    const int *qa = &a;
    const int *qb = &b;
    
    /* 情形1 */
    int* const &i = pa;    // 不能通过引用i改变被引用对象pa的值
    // int* const &i = &a; // 这时可以直接引用地址,因为i是常引用,&a就是常量 
    // i = pb;             // 是错误的,会报错
    *i = 3;                // 但是可以通过*i改变pa所指对象的值,相当于*pa = 3
    cout << a << endl;     // 输出3,代表pa所指对象---a的值被改变

    /* 情形2 */
    /* j是const int* 类型的引用,q也必须是const int*类型;
       j不能通过*j改变j所引用的对象的值,但是可以通过j改变被引用对象q的值 */
    const int* &j = qa;
    // *j = 4;   // 是错误的,会报错
    j = pb;      // 通过引用j改变被引对象qa的值为qb,相当于qa = pb
    cout << *qa << endl;  // 输出为b的值--2,说明通过j改变qa的值为pb,即&b

    /* 情形3 */
    /* 这种情况,既不能通过k改变pa的值,也不能通过*k改变pa所指对象的值 */
    const int* const &k = pa;
    // k = pb;   // 是错误的,会报错
    // *k = 5;   // 是错误的,会报错
    const int* const &k = &a;  // 这时可以直接引用地址,因为i是常引用,&a就是常量

    system("pause");
    return 0;
}

最后这里需要注意一点:

#include<iostream>
using namespace std;

int main()
{
    int a = 1;
    int b = 2;
    int *pa = &a;
    int *pb = &b;
    const int *qa = &a;
    const int *qb = &b;
   
    const int* &j = qa;        // j是const int*类型的引用,qa也必须是这种const类型指针
    const int* const &k = pa;  // 而k,所引用的pa可以不用是const类型,尽管它们都有相同的开头

    system("pause");
    return 0;
}

本人水平有限,若有误,欢迎评论留言指教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值