容易混淆的const
关键字const并不能把变量变为常量!在一个符号前加上const限定符只是表示这个符号不能被赋值。也就是他的值对于这个符号来说是只读的,但它并不防止通过程序的内部的方法来修改这个值。const最有用之处就是他来限定函数的形参,这样该函数将不会修改实参指针所指的数据,但其他的函数却可能会修改它。
const 有哪些作用?
(1)可以定义const常量,具有不可变性。 例如:const int Max=100; Max++会产生错误; (2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。 例如: void f(const int i) { …} 编译器就会知道i是一个常量,不允许修改; (3)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。 还是上面的例子,如果在函数体内修改了i,编译器就会报错; 例如: void f(const int i) { i=10;//error! } (4) 可以节省空间,避免不必要的内存分配。 例如: #define PI 3.14159 //常量宏 const double Pi=3.14159; //此时并未将Pi放入ROM中 … double i=Pi; //此时为Pi分配内存,以后不再分配! double I=Pi; //编译期间进行宏替换,分配内存 double j=Pi; //没有内存分配 double J=PI; //再进行宏替换,又一次分配内存! const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干份拷贝。 (5) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
举例
例一 下面分别用const限定不可变的内容是什么? 1)const在前面
const int nValue; //int是const
const char *pContent; //char是const, pContent可变
const char* const pContent; //pContent和*pContent都是const
2)const在后面,与上面的声明对等
int const nValue; //nValue是const
char const * pContent; //*pContent是const, pContent可变
char* const pContent; //pContent是const,*pContent可变
char const* const pContent; //pContent和*pContent都是const
分析: const只修饰其后的变量,至于const放在类型前还是类型后并没有区别。如:const int a和int const a都是修饰a为const。 注意不是一种类型,如果pType之前是某类型,那么pType是指向该类型的指针 一个简单的判断方法:指针运算符*,是从右到左,那么如:char const * pContent,可以理解为char const (* pContent),即* pContent为const,而pContent则是可变的。 例二
int const * p1,p2;
p2是const;(p1)是一整体,因此(p1)是const,但p1是可变的。int * p1,p2只代表p1是指向整型的指针,要表示p1、p2都是指针是需写成int * p1, p2。所以无论是 const p1,p2还是const * p1,p2,里面的*都是属于p1的。 例三
int const * const p1,p2;
p2是const,是前一个const修饰的,*p1也被前一个const修饰,而p1被后一个const修饰。 例四
int * const p1,p2;
p1是const,(* const p1)是整体,所以const不修饰p2。 例五 指针指向及其指向变量的值的变化 const在的左边,则指针指向的变量的值不可直接通过指针改变(可以通过其他途径改变);在的右边,则指针的指向不可变。简记为“左定值,右定向”。 1)指针指向的变量的值不能变,指向可变
int x = 1;
int y = 2;
const int* px = &x;
int const* px = &x; //这两句表达式一样效果
px = &y; //正确,允许改变指向
*px = 3; //错误,不允许改变指针指向的变量的值
2)指针指向的变量的值可以改变,指向不可变
int x = 1;
int y = 2;
int* const px = &x;
px = &y; //错误,不允许改变指针指向
*px = 3; //正确,允许改变指针指向的变量的值
3)指针指向的变量的值不可变,指向不可变
int x = 1;
int y = 2;
const int* const px = &x;
int const* const px = &x;
px = &y; //错误,不允许改变指针指向
*px = 3; //错误,不允许改变指针指向的变量的值
补充 在c中,对于const定义的指针,不赋初值编译不报错, int* const px;这种定义是不允许的。 int const px;这种定义是允许的。 但是,在C++中 int const px;和const int* const px;会报错,const int* px;不报错。 必须初始化指针的指向int* const px = &x;const int* const px=&x;
- Python之numpy数组学习(二)
- Intent 属性详解(上)
- 复仇行动:Notepad++官网被圣战组织黑了
- 四大组件的纽带——Intent
- 利用HTC One漏洞破解手机PIN密码
- Android NDk环境配置
- 谷歌再曝Windows8.1漏洞,微软怒了
- Python机器学习的生态系统
- TP-link TL-WR840N系列路由器存在CSRF漏洞,可修改任意配置(含POC测试过程)
- JavaScript严格模式
- 微软修复8个安全漏洞,包括谷歌披露的0day漏洞
- PullToRefreshScrollView 嵌套RecyclerView实现特卖列表倒计时抢购
- 全栈数据工程师养成攻略:Python 基本语法
- 从卷积神经网络的角度看世界
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- DHCP 中继实验
- 【NBA 可视化】使用Pyecharts实现湖人19-20赛季投篮数据可视化~
- 微信小程序开发实战(18):地图组件
- 教你几招,快速创建 MySQL 五百万级数据,愉快的学习各种优化技巧
- 【Pyecharts】2014-2019年高考数据可视化~
- 25.Python的循环与递归
- 26.Python文件内容的迭代
- 28.Python中对象的特性
- 如何基于jackson动态序列化指定字段
- c/c++补完计划(五): 平衡二叉树和二叉搜索树
- 【原创】Java并发编程系列30 | ThreadLocal
- c/c++补完计划(六): 语法糖lambda
- 从别人的代码中学习golang系列--03
- Flink写出数据到HBase的Sink实现
- 「MoreThanJava」Day 4:面向对象基础