const修饰符限定的常量
类型前加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修饰符限定的常量的更多相关文章
- const修饰符与函数
一.用const修饰函数的参数 函数参数类型前加const指明该参数为常量,在函数内部不可改变. void func(const int x) { //x不可以在内部进行赋值等操作. } 注:当参数为 ...
- [C++]const修饰符
Date: 2014-1-1 Summary: const 修饰符笔记 Contents: 1.const 修饰符 声明一个常量数据类型 , 在编译时就确定数据类型 2.const 与 指针 一般情况 ...
- C++中 容易忽视的const 修饰符
C++可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的有点: (1)const常量有数据类型,而宏常量没有数据类型.编译器可以对const进行类型安全检查,而后者只进行 ...
- C/C++ 中 const 修饰符用法总结
C/C++ 中 const 修饰符用法总结 在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家 ...
- [原创] 基础中的基础(二):C/C++ 中 const 修饰符用法总结
在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家梳理一下知识,给大家一点点帮助.作者是菜鸟一 ...
- 转载----C/C++ 中 const 修饰符用法总结
感谢原创作者,写的好详细.不忍错过,所以转载过来了... 原文地址: https://www.cnblogs.com/icemoon1987/p/3320326.html 在这篇文章中,我总结了一些C ...
- C++ c++与C语言的区别(三目运算符,const修饰符)
//区别⑦:三目运算符(C++版本) #include<iostream> using namespace std; //三目运算符 C语言返回变量的值 C++语言是返回变量本身 void ...
- Delphi 中 函数参数中的 const 修饰符的本质以及注意事项
来自:http://blog.csdn.net/farrellcn/article/details/9096787 ------------------------------------------ ...
- 字符串输出输入函数,const修饰符,内存分区,动态内存管理,指针和函数,结构体
1.字符串输出输入函数 读入字符串的方法: 1) scanf 特点:不能接收空格 2) gets 特点:可以接受含有空格的字符串 ,不安全 3) fgets(); 特点:可以帮我们自动根据数组的长度截 ...
随机推荐
- 使用HostAliases 添加pod 的/etc/hosts
默认的pod 的/etc/hosts 无法自动数据 [root@master1 ~]# kubectl exec smsservice-5c7ff5f74-bc969 -n testihospital ...
- 分布式爬虫之elasticsearch基础6(bluk)
上篇文章介绍了在es里面批量读取数据的方法mget,本篇我们来看下关于批量写入的方法bulk. bulk api可以在单个请求中一次执行多个索引或者删除操作,使用这种方式可以极大的提升索引性能. bu ...
- dubbo报错Data length too large: 10710120处理,及服务提供者协议配置详细说明
工作中遇到以下报错信息 cause: java.io.IOException: Data length too large: 10710120, max payload: 8388608, chann ...
- lombok的使用和原理
一.项目背景 在写Java程序的时候经常会遇到如下情形: 新建了一个Class类,然后在其中设置了几个字段,最后还需要花费很多时间来建立getter和setter方法 lombok项目的产生就是为了省 ...
- 1499-luogu洛谷 后缀表达式
题目描述 所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级). 如:3*(5–2)+7对应 ...
- AI 数值计算
数值计算,通过迭代来更新解的估计值. 1.上溢和下溢 实数按照一定的精度存储在计算机中,通常存在误差,进而可能导致一些错误. 1)下溢(underflow),例如接近0的数 2)上溢(overflow ...
- Qt 中一些常用类中文说明
Qt 中一些常用类中文说明是本文讲述的内容,这篇文章主要是介绍Qt 当中经常使用的类,采取的是使用字母索引的方式,下面的类是被经常使用的. QDataStream 为QIODevice提供了一串的二进 ...
- android 权限动态申请
名字其实有点让人感觉高大上"权限动态申请",其实也没有什么, 以前做Android程序的时候,比如需要打开摄像头 那么需要在 然后就可以了, 但是Android6.0之后呢,有些权 ...
- GIT 安装、创建版本库
在Linux上安装Git 首先,你可以试着输入git,看看系统有没有安装Git: $ git The program 'git' is currently not installed. You can ...
- IOC框架之Ninject 简介
还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 上篇博客介绍了依赖注入的三种方式:构造方法注入,属性注入,接口注入!详情请参考 ...