const与*

本文详细解析了C++中const与指针的各种用法,包括const修饰符的就近原则,以及不同组合如const int* p1, int* const p2, const int* const p2的区别与应用场景。
摘要由CSDN通过智能技术生成
 前言:在csdn中看到一个帖子,是关于const和*的问题,借此机会抽了点时间,把几种情况用“就近原则”解析了一遍。希望对困惑的人有些帮助。其中引用了帖子中一些楼主的原话,没有注明其网名,特此声明!

#include <iostream>

using namespace std;

int main()
{
    const int i = 1;
    int j = 10;
    int k = 20;
    const int * a = &j;//a指向j;a可变,a指向的对象不可变
    cout << "a1=" << *a << endl;
    a= &k;  //①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
    cout << "a2=" << *a << endl;
    k=5;    //②此时a指向k,不是说a指向的对象不可变吗???
    //*a=5;//③a指向的对象值不可变,编译出错,*a不就是k吗???
    cout << "a3=" << *a << endl;

}
/*
这些是楼上的不错的回答(回答的楼主,就不注明了)

/
①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
当然可以,不过用a还是改不了值。a被声明为const char *,编译器会做判断。
②此时a指向k,不是说a指向的对象不可变吗???
可以用k改,但不能用a改
③a指向的对象值不可变,编译出错,*a不就是k吗???
同上。

//
首先const是依靠编译器来实现的,并非说他修饰的变量或者对象在内存就一定要放在
常量区。所以这也是为什么我们一旦在代码中有修改该变量或者对象的时候就会编译错
误,而不是说运行的时候报错。

你常量指针a指向一个非常量这个是完全合理的。当你这么做的时候意味着你不能通过
该指针来修改它所指的对象,但是并不是说你不能直接修改该对象。这也就是为什么
你可以直接给k赋值来修改它。

/
const int* a
*a是常量,不能通过*a=xxx来赋值 a本身是可以改变,即可以修改所指向的内存地址,
但不能修改指向对象的值 但k自己改变值是k自己的事情 和a无关 a只是不能修改k的值
而已

/
const int * p1;
int * const p2;
const int * const p2;
三者是不一样的,指向常量,常量地指向,常量地指向常量

*/

/*解析“就近原则”,来辨别const与*的相关问题

A:const int * p1;
B: int const * p1;
C: int * const p2;
D: const int * const p2;
E:int const * const p2;
F: const 函数(超出这里要探讨的范围,不解析,只是提名一下)

A:const int * p1;
const和int就近,那么const修饰的就是一个int数据,换言之,这个int数据将被用作
常量,而不论他本身是不是常量。然后看后面的内容是*p1,那么p1就是一个指向“常量”的
一个整型指针。(注意引号的意义)

如何应用呢?
    当给这个指针p1一个地址之后,当然这个地址肯定是一个整型变量的的地址(注意这里
并没有强调这个整型变量是一个常量),如果这个整型变量不是常量,可以通过原变量本
身修改其值,而不能通过指针来修改其值;如果是常量,那么甭想修改了。
    另外,由于const修饰的只是int,而没有影响到p1,那么p1依旧是一个变量,可以
根据需要改变其指向。

优点:
    当需要访问一个变量的时候,为了避免对其值修改的可能,就是通过这样的用法实现
    即:只能访问,不能修改。“只能看,不能摸”——你懂得!

int main()
{
    const int i = 1;
    int j = 10;
    const int * a = &j;//a指向j,j不是常量
    cout << "a1=" << *a << endl;

    //*a=20;//非法
    j=20;//可以绕个圈,通过j本身修改,来达到*a的变值。
    cout << "a1=" << *a << endl;

    a=&i;//修改指向,由于i本身就是const,那么i值一定不会变
    cout << "a1=" << *a << endl;
    return 0;
}*/
/*
B: int const * p1;
const 和*接近!修饰整个*p1,又由于*p1本身就等价于一个整型变量,因此它和A等价
*/

/*
C: int * const p2;
const和p2就近,那么const修饰p2。即:p2是一个常指针。一旦赋值,不可改变。“一次定
终身那!”,指向只能“嫁鸡随鸡嫁狗随狗”了。无论鸡狗如何,也只能凑合,用一句台词
“凑合过吧,还能离咋滴?!”说实话:这里离的权利都没有,除非销毁指针!
    同样,它指向可以是变量也可以是常量!不过这里可以通过指针修改指向变量的值,
如果它指向的是一个变量而不是常量的话!
优点:
    有其本质决定。即:需要一个不改变指向的指针。当一名看家狗!十分敬业!
int main()
{
    const int i = 1;
    int j = 10;
     int * const a= &j ;//a指向j,j不是常量
    //注意这里不能通过先声明后赋值的方法。a有且仅有一次赋值机会,而且和声明同步
    cout << "a1=" << *a << endl;

    *a=20;//合法
    cout << "a1=" << *a << endl;

    j=30;//也可以绕个圈,通过j本身修改,来达到*a的变值。
    cout << "a1=" << *a << endl;

    //a=&i;//非法
    return 0;
}
*/
/*
D: const int * const p2;
const int 和AB一致,* const p2和C一致。因此这就是ABC的“变异体”,或者说“结合体”
因此它会拥有ABC的所有特性与优点。说白了,就是杂交品种,比较优良!
还是下个定义吧:它是一个指向整型“常量”的整型常指针!

同理E:int const * const p2;也就和D等价

int main()
{
    const int i = 1;
    int j = 10;
    const int * const a= &j ;//a指向j,j不是常量
    //注意这里不能通过先声明后赋值的方法。a有且仅有一次赋值机会,而且和声明同步
    cout << "a1=" << *a << endl;

    //*a=20;//非法

    j=30;//依旧可以绕个圈,通过j本身修改,来达到*a的变值。
    cout << "a1=" << *a << endl;

    //a=&i;//非法
    return 0;
}
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值