类型前加const修饰符限定变量为只读,称为常量,定义时必须初始化,且初始化后编译器不允许再修改常量的值。

一、常量的定义##

const在类型前面

const int value;                  //value是const
const char *value; //*value是const, value可变
const (char *) value; //value是const,*value可变
char* const value; //value是const,*value可变
const char* const value; //value和*value都是const

const在类型后面

int const value;                // value是const
char const * value; // *value是const, value可变
(char *) const value; //value是const,*value可变
char* const value; // value是const,*value可变
char const* const value; // value和*value都是const

总结

const在\(*\)左侧指针所指的值不可改变,const在\(*\)右侧指针不可改变。

二、常量(const)与变量(non-const)之间的转换##

non-const转化为const

int a = 10;
const int b = const_case<const int>(a);

const_case<const \([type]\)>(\([data]\))会返回non-const。

一般不用,因为直接\(int b = a\)就好,因为\(a\)作为常量可以直接赋给变量

const转化为non-const

const int a = 10;
int b = const_cast<int>(a);

const_cast<\([type]\)>(\([data]\))可用于去除const。

三、常量(const)与变量(non-const)之间的赋值##

1.常量在初始化后就不可以再被赋值。###

2.常量赋值给变量###

一般的常量赋值给变量没有问题,但指针所指的值为const时要利用变换const_cast去const限定。

可以理解为指针所指的值限定为const时,编译器限定该地址下所存的为常量只读,而赋给普通指针时,普通指针默认改地址下存的为变量可以被更改。然而同一地址下不可能即为常量又为变量,所以报错。

const int a = 10;
int b = a; //正确
const int* c = &a;
int *d = c; //报错
int *e = const_cast<int*> (c); //正确

注:此时通过e来更改地址下所存的数据,c的值也会被更改,但会出现如下现象:

    const int c = 10;
int *e = const_cast<int*> (&c);
(*e)++; cout << "c address= " << &c << endl;
cout << "e adderss= " << e << endl;
cout << "c value= " << c << endl;;
cout << "e value= " << *e << endl; //输出为
// c address= 0x7ffde623acb4
// e adderss= 0x7ffde623acb4
// c value= 10
// e value= 11

虽然地址相同但却存着不同的值,猜想可能的原因在于编译器进行了优化,由于寄存器访问的速度远远超过内存访问速度,因此编译器会将部分数据存储在寄存器中,需要时直接从寄存器中取出。本题数据类型为const,编译器认为数据不会被修改,因此放心大胆从寄存器中取值了,但是事实上内存中的数据已经被修改了。

如何来验证上面的猜测呢,当然是禁止编译器优化了,可以使用volatile关键字禁止编译器的优化,这样编译器每次都不得不从内存中取数据,这样在内存中数据被修改后就会相应修改了。

    volatile const int c = 10;
int *e = const_cast<int*> (&c);
(*e)++; cout << "c address= " << &c << endl;
cout << "e adderss= " << e << endl;
cout << "c value= " << c << endl;;
cout << "e value= " << *e << endl; //输出为
// c address= 1
// e adderss= 0x7ffd2e357204
// c value= 11
// e value= 11

可以看到值变为相同的了,但地址变为1了,小生也不知道为什么(:

const修饰符限定的常量的更多相关文章

  1. const修饰符与函数

    一.用const修饰函数的参数 函数参数类型前加const指明该参数为常量,在函数内部不可改变. void func(const int x) { //x不可以在内部进行赋值等操作. } 注:当参数为 ...

  2. [C++]const修饰符

    Date: 2014-1-1 Summary: const 修饰符笔记 Contents: 1.const 修饰符 声明一个常量数据类型 , 在编译时就确定数据类型 2.const 与 指针 一般情况 ...

  3. C++中 容易忽视的const 修饰符

    C++可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的有点: (1)const常量有数据类型,而宏常量没有数据类型.编译器可以对const进行类型安全检查,而后者只进行 ...

  4. C/C++ 中 const 修饰符用法总结

    C/C++ 中 const 修饰符用法总结 在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家 ...

  5. [原创] 基础中的基础(二):C/C++ 中 const 修饰符用法总结

    在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家梳理一下知识,给大家一点点帮助.作者是菜鸟一 ...

  6. 转载----C/C++ 中 const 修饰符用法总结

    感谢原创作者,写的好详细.不忍错过,所以转载过来了... 原文地址: https://www.cnblogs.com/icemoon1987/p/3320326.html 在这篇文章中,我总结了一些C ...

  7. C++ c++与C语言的区别(三目运算符,const修饰符)

    //区别⑦:三目运算符(C++版本) #include<iostream> using namespace std; //三目运算符 C语言返回变量的值 C++语言是返回变量本身 void ...

  8. Delphi 中 函数参数中的 const 修饰符的本质以及注意事项

    来自:http://blog.csdn.net/farrellcn/article/details/9096787 ------------------------------------------ ...

  9. 字符串输出输入函数,const修饰符,内存分区,动态内存管理,指针和函数,结构体

    1.字符串输出输入函数 读入字符串的方法: 1) scanf 特点:不能接收空格 2) gets 特点:可以接受含有空格的字符串 ,不安全 3) fgets(); 特点:可以帮我们自动根据数组的长度截 ...

随机推荐

  1. JavaScript中的typeof操作符用法实例

    在Web前端开发中,我们经常需要判断变量的数据类型.鉴于ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型——typeof就是负责提供这方便信息的操作符.   对一个值使用t ...

  2. 如何使用Simulink模糊控制

    在用这个控制器之前,需要用readfis指令将fuzzy1.fis加载到matlab的工作空间,比如我们用这样的指令:fis1=readfis(‘fis1.fis’):就创建了一个叫myFLC的结构体 ...

  3. mysql编码问题:

    在my.ini文件改为: [client]default-character-set = utf8port=3306 [mysql] default-character-set=utf8 [mysql ...

  4. Linux 局域网同步时间

    选择一台能上外网的机器作为时间服务器(都不能上亦可以,任选一台即可,但是只能保证局域网内时间同步) 配置此时间服务器 安装 ntp 在 /etc/ntp.conf 中配置 restrict 127.0 ...

  5. 查看Orcale数据里的表是否有变化

    由于我们公司一个数据库两个应用在使用,导致一个应用修改了数据库,另一个应用用的缓存而不知道有更新还是原来的结果.原来的处理方式是采用session缓存的方式,用户登出了就清空缓存,这样只需要重新登录一 ...

  6. BesLyric 全新版本下载 ( windows \ mac \ linux )

    导读 BesLyric , 一款专门制作 网易云音乐 LRC 滚动歌词的软件! 搜索.下载.制作 歌词更方便! 很荣幸地,自 beslyric 2017 年开发推出以来,得到了很多云村村民的肯定,现在 ...

  7. vbox虚拟机和vm虚拟机 虚拟机网络不通的解决方法

    vm网络不通的情况: 第一步 :打开物理机, 选中“计算机”*(,右键—管理—服务,找到以VM开头的服务,选中后,右键—启动,就可以了.如图: 第二步: 这样基本就可以了,如果还不行 如果重启失效了, ...

  8. React-简书视频学习总结

    react的基础语法 redux这个数据层框架 react-redux如何方便我们在react中使用redux react-router 4.0 这样的非常实用的相关的第三方模块儿 immutable ...

  9. 微信小程序 wx.getUserInfo 解密 C# 代码 - 转

    public static string DecodeUserInfo(string raw, string signature,string encryptedData, string iv) { ...

  10. 使用Win PE修改其他硬盘中的系统注册表

    使用场景:原来装的机械硬盘系统盘为C盘,后来买了个SSD固态硬盘后,进入WinPE系统后,把原来的C盘整个复制到了固态硬盘,然后用BooticeX64.exe工具在UEFI启动中增加SSD固态硬盘中的 ...