const int | int const | const int * | int* const

转载自 https://blog.csdn.net/huangchijun11/article/details/72725463


const的四种用法

ref @ https://blog.csdn.net/xingjiarong/article/details/47282255

  1. 修饰value 表示是个常量值
  2. 修饰指针(指针常量 和 常量指针)
  3. 修饰函数 (也是分为三种,具体哪三种)
  4. 修饰函数返回值

如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。


例如函数
const char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();
正确的用法是
const char *str = GetString();

小总结

  • const放在变量/类实例名前面,表示你不能修改这个变量/类实例的内容 (仅此而已 ,该变量/类实例本身并不要求一定要是常类型 )【防止修改指针指向的内容】
  • const放在变量名后面,表示这个指针就和这个变量名绑定了 【防止修改指针指向的地址】
  • 还有一种是以上两种的结合



前言:很多人都把const int * 、int * const、int const* 的区别和联系搞混,我自己在学习C++的过程中,也经常性 弄不 清楚,今天特意总结一下,作为学习笔记记录下来。

一,const修饰符用于指针

【常量指针】

  • 将const用于指针有些很微妙的地方,有两种不同的方式将const关键字用于指针。第一种方法是让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值,第二种方法是将指针本身声明为常量,这样可以防止改变指针的位置。

    声明一个指向常量的指针a:

        int y = 1;
        const int * a = &y;

该声明指出,a指向一个const int,这里为1,因此不能使用a来修改这个值。换句话说,*a的值为const,不能被修改,但是a的声明并不意味着它指向的值实际上就是一个常量,而只是意味着 对a而言,这个值是常量。a指向y,而y不是const,可以通过y变量来修改y的值,但不能使用a指针来修改。

        const int m = 9;
        const int * n = &m;  // (1)
        int * t = &m;            //(2)

上面的(1)和(2)中看到了什么,(2)将const的地址赋给了常规指针,(1)将const地址赋给了const指针,这两张是否正确呢,答案显然(2)不对,因为C++禁止将const的地址赋给非const指针,如果非要这样做,只能使用强制类型转换来突破这种限制。

        int m = 1;
        const int * n = &m;  //(3)
        int * const h = &m;  //(4)

(3)中声明的const只能防止修改n指向的值,而不能防止修改n的值,也就是说可以将一个新地址赋给n;但仍然不能使用n来修改它指向的值,不允许使用n来修改m的值,但允许将n指向另一个位置。(4)中关键字const的位置与之前的不同,这种声明格式使得h只能指向m,但允许使用h来修改m的值。


划重点

  • 常量指针不一定要指向常量,其含义只是不能通过常量指针修改指针所指向的内容而已
  • 所以我们可以有两种方式修改常量指针指向地址的值
    • change int m to other values
    • change const int to refer to another value’s address


int const * 与const int *

int const * a 与const int * a是没有任何区别的,它们的效果是一样的,都表示a指向一个const int,它总是把它指向的目标当做一个int常量。不能使用a来修改这个指向的地址的值,但是可以重新指向其他地址。即*a的值是const,不能被修改。

两者都是常量指针
记忆方法 : 常量(const)在指针(*)前面,所以连起来读作常量指针



【指针常量】

指针常量是指指针本身是个常量,不能在指向其他的地址,写法如下:

int *const n;

需要注意的是,指针常量指向的地址不能改变,但是地址中保存的数值是可以改变的,可以通过其他指向改地址的指针来修改。

int a=5;
int *p=&a;
int* const n=&a;
*p=8;

const int * const 与 const int const *

        int trouble = 2;
        const int * const flag1 = &trouble;  //(5)
        const int const * flag2 = &trouble;  //(6)

其中(5)flag1只能指向trouble,而flag1不能用来修改trouble的值,即flag1和flag1都是const。指向的地址和指向的地址的值都不能改变。
其中(6)同(5)的用法类似,也是指针指向的内存地址不可变,并且指针指向的内存地址的值也不能被修改。
讲道理,const int
const 才是最标准的第三种的用法( 防止修改指针指向的地址 & 防止指针修改指向的内容的结合版 ),但是由于const int const* 我们也能看出来是想结合两种,所以也算进来了(如果只有一个const,const还在*前面 ,我们就不好说了不是,所以只有一个const、const还在 * 前面的情况我们就还是归在常量指针的范畴内)


小总结

  • 区分常量指针和指针常量的关键就在于星号的位置,我们以星号为分界线,如果const在星号的左边,则为常量指针,如果const在星号的右边则为指针常量。(const int const * 比较例外,详情看上方 )



四,牛客网例题分析

请声明一个指针,其所指向的内存地址不能改变,但内存中的值可以被改变。
在这里插入图片描述

  • 我们始终记住若const限定符在*之前,则const限定的是*ptr而不限定ptr。也就是说,ptr可以改变其所指向的对象,但不能通过该指针修改其所指向对象的值。

  • 若const限定符在*之后,则const限定的是ptr而不限定*ptr。也就是说,ptr不可以改变其所指向的对象,但能通过该指针修改其所指向对象的值。

  • 若在*之前有const限定符且在*之后也有const限定符,则ptr与*ptr都被限定。也就是说,ptr既不可以改变其所指向的对象,也不能通过该指针修改其所指向对象的值。
    只要在*之后有const 限定符,则该指针在声明时必须初始化。

    A中指向的内存地址不可变,指向的内存地址的值也不可变
    B中指向的内存地址不可变,但是指向的内存的地址的值可以改变。
    C中指向的内存地址可以改变,但是指向的内存的地址的值不能改变。
    D中指向的内存地址可以改变,但是指向的内存的地址的值不能改变。
    E中指向的内存地址不可变,指向的内存地址的值也不能改变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值