本篇主要来介绍C++中用于定义常量的关键字const,它解决了C中的宏定义无法指定数据类型的缺点,在定义时就指明数据类型,定义了一个不可改变的常量值
(就看这一句基本就可以了)。
性质总结放于前:
- 用于修饰变量,将变量变成常量(常量一旦定义,就不可修改);
- 编译器在程序的编译时期做的检查;
- 使用常量来代替宏定义,在定义时指明数据类型,定义时进行赋值;
- 可以是全局也可以是局部的;
- 由于编译优化的存在,只有编译时不确定的常量才可以通过指针修改运行时的值。
1. C语言中宏定义的使用
在C中计算圆的面积,其中PI的固定值,常用的方法如下:
#include <iostream>
//C命令中写法
//宏的编译本质上是文本级的替换,在编译之前用pi对3.14替换,但未指定数据类型
#define PI 3.14
//main函数其实有参数的
//int nArgc为命令函参数个数,char* pArgv[]为命令行参数指针数组
int main(int nArgc, char* pArgv[])
{
float r = 0.5;
float n = PI*r*r;
}
但是这里有一个问题:宏的编译本质上是文本级的替换,在编译之前用pi对3.14替换,但未指定数据类型,没有类型的检查
。
2. C++新的关键字const
为了定义常量并指定数据类型,C++中提出一个新的关键字const,对应的用法如下:
const float FPI = 3.14;
#include <iostream>
//常量--变量
const float FPI = 3.14;
int main(int nArgc, char* pArgv[])
{
float r = 0.5;
float n = FPI*r*r;
}
3. 常量与变量区别
常量是与变量相对应的,变量在程序运行中可能会发生变化,常量则是在程序整个声明周期中是不变的。
3.1 常量一旦定义无法再赋值
常量一旦定义,是无法赋值的,变量则是可以赋值的。我们可以对上面的代码进行修改,得到如下:
#include <iostream>
#define PI 3.14
//常量--变量
const float FPI = 3.14;
int main(int nArgc, char* pArgv[])
{
float r = 0.5;
FPI = 1.11f;
float n = FPI*r*r;
}
运行结果:可以看到编译后显示常量不可以被赋值
const修饰变量,将变量变为常量(常量一旦定义就不可以修改),并且常量在定义的时候就需要赋值,否则后期是无法赋值的
3.2 常量在内存中的分配
变量在程序运行时是分配了运行空间的,常量是否分配运行控件呢?我们可以通过指针来查看。
下面一段代码
#include <iostream>
#define PI 3.14
//常量--变量
const float FPI = 3.14;
int main(int nArgc, char* pArgv[])
{
float r = 0.5;
//float* p = &PI;//报错:无法从“const float *”转换为“float *”
//常量不可改,但是编译器又给其分配了空间,通过指针来改变
float* p = (float*)&FPI; //利用(float*)进行强转即可读取其地址;
float n = FPI*r*r;
}
F10单步运行之后:可以看到是常量也是分配了内存的
小技巧: 从内存中查看数据类型,从右往左看,40开头代表其数据类型为浮点型
。
3.3 通过指针在内存中修改常量
常量是不可以修改的,但是编译器又给分配了内存空间,直接通过指针修改,其值就发生了变化
。
下面通过指针来修改内存值:
(1)查看r
对应值在内存中的表示方法
(2)手动修改p
指向的内存值,使其等于r
对应的值
常量无法修改是在什么时候检查的?
1.程序的编译时期–无法修改
2.程序运行时期–是可以通过内存修改的
3.3.1 编译时确定常量在内存中的修改
下面看一下通过内存修改是否会影响编译结果:无代码去想,都在内存中修改了,编译结果肯定发生改变呀!那就看看下面代码结果:
#include <iostream>
#define PI 3.14
//常量--变量
const float FPI = 3.14;
int main(int nArgc, char* pArgv[])
{
const int nConst = 5;
printf("nConst=%d\r\n", nConst);
return 0;
}
运行结果:
(1)常量赋值之后在其内存中将其修改为4
(2)进行打印后结果仍为5
结论: 即使内存中修改了,但是编译器进行了优化,编译时将代码中的常量直接用数字5代替,printf("nConst=%d\r\n", nConst);
也就相当于printf("nConst=%d\r\n", 5);
。
3.3.2 编译时不确定常量在内存中的修改
那如果我还是想修改常量呢?前面的结果是由于编译器知道
nConst
具体值为5,那如果让编译器不确定
nConst
值就可以实现修改了。
代码如下:int main(int nArgc, char* pArgv[])
中nArgc
的值在编译时是无法知道的,只有运行才可以知道
#include <iostream>
#define PI 3.14
//常量--变量
const float FPI = 3.14;
//main函数其实有参数的
//int nArgc为命令函参数个数,char* pArgv[]为命令行参数指针数组
int main(int nArgc, char* pArgv[])
{
//换成命令函参数个数nArgc后,编译器不能提前知道值,因此在运行时内存中的修改便会生效
const int nConst = nArgc;
printf("nConst=%d\r\n", nConst);
return 0;
}
运行结果:
(1)F10单步调试修改nConst值
(2)打印结果为修改后的2
结论: 编译时不确定值的常量,在运行时修改内存即可实现修改常量的目的
。
4. 学习视频地址:C++57个入门知识点_02_const常量限制