const是一个限定符,被const限定的变量其值不会被改变。
目录
1、修饰变量
指向的变量的值不可改变,次数说的不可改变只是不能通过变量本身去改变,如果我们通过指针,还是可以去实现改变的。
在C中,可以通过指针去改变一个const修饰的局部变量的值,注意我加粗的部分,如果是const修饰的全局变量,则无法通过指针去改变。这是因为:
const修饰的全局变量被放在了只读数据区,不能修改,
而const修饰的局部变量存放在栈区,可以修改。
具体案例
修改的局部变量
//C中,使用指针修改const修改的局部变量
#include<stdio.h>
int main()
{
const int a = 1;
int * p = (int *)&a;
//尝试改变其所指向的值
*p = 3;
printf("P指向的值是%d\n",*p);
return 0;
}
修改成功
修改全局变量
//C中,使用指针修改const修改的全局变量
#include<stdio.h>
const int a = 1;
int main()
{
int * p = (int *)&a;
//尝试改变其所指向的值
*p = 3;
printf("P指向的值是%d\n",*p);
return 0;
}
修改失败
此外,这块东西在C和C++编译器下还有些不同,从前面的测试结果来看,在C中是可以通过指针去修改一个const修饰的局部变量的值的,但是这在C++中却又是不行的,在C++中变量求值的地方直接替换为立即数,因此不能修改。
#include<iostream>
using namespace std;
int main()
{
const int a = 1;
int * p = (int *)&a;
*p = 3;
printf("a变量的值是%d\n", a );
return 0;
}
2、修饰指针
const修饰指针创建了一个指针常量,但是const的位置会导致这个指针常量有不同的含义。
分为指向常量的指针(pointer to const)和自身是常量的指针(常量指针,const pointer);
(1)指向常量的指针,限定其指向的值。指针的指向可以改变,但是指针所指向的变量的值不可改变。
尝试改变指向
#include<stdio.h>
int main()
{
int a = 1,b = 2;
const int * p = &a; //const修饰的是int *,限定的是指向的值
//p的指向还是可以变的
p = &b;
printf("P指向的值是%d\n",*p);
return 0;
}
result
尝试改变指向变量的值
#include<stdio.h>
int main()
{
int a = 1,b = 2;
const int * p = &a; //const修饰的是int *,限定的是指向的值
//尝试改变其所指向的值
*p = 3;
printf("P指向的值是%d\n",*p);
return 0;
}
result
(2)自身是常量的指针,限定其指向。指针的指向不可改变,指针所指向的变量的值可以改变。
尝试改变其指向
#include<stdio.h>
int main()
{
int a = 1,b = 2;
int * const p = &a; //const修饰的是p,限定的是其指向
//尝试改变其指向
p = &b;
printf("P指向的值是%d\n",*p);
return 0;
}
result
尝试改变指向变量的值
#include<stdio.h>
int main()
{
int a = 1,b = 2;
int * const p = &a; //const修饰的是p,限定的是其指向
//尝试改变其指向的变量的值
*p = 3;
printf("P指向的值是%d\n",*p);
return 0;
}
result
3、修饰引用
const是修饰一个变量为常量,引用是对一个变量取别名(注意引用在初始化时必须和对应变量相关联),通过改变其引用来改变其原变量,二者一结合,用const修饰引用。
此时,不能通过引用修改原始值,若要修改只能通过直接修改原变量的方式修改。
#include<iostream>
using namespace std;
void func(const int & a)
{
a = a + 1;//尝试去修改
}
int main()
{
int x = 1;
func(x);
return 0;
}
result
只能通过更改原始变量改变其值
#include<iostream>
using namespace std;
void func(const int & a)
{
cout<<"引用的值是"<<a<<endl;
}
int main()
{
int x = 1;
func(x);
x = x + 1;
cout<<"改变原始值后是"<<x<<endl;
return 0;
}
result
修饰指针,const既可以限定其变量的值,也可以限定指针的指向
修饰引用,const只能限定其变量的值,并且只是限定引用取别名的那个量
这是因为引用只是对象的别名,引用不是对象,不能用 const 修饰
另外,在const修饰的引用中,如果引用类型与初始化变量类型不一致,会生成临时变量,修改变量不会修改引用的临时变量的值。
4、修饰成员函数
使用的时候放在函数末尾
将const修饰的类成员函数称之为const成员函数。const修饰类成员函数,实际修饰该成员函数隐含的 this 指针,这表明在该成员函数中不能对类的任何成员进行修改。
#include<iostream>
using namespace std;
class A
{
public:
void test(void) const;
private:
int a;
};
void A::test(void) const
{
a++;
cout<<"a的值是:"<<a<<endl;
}
int main()
{
A a;
a.test();
return 0;
}
result
5、宏定义 #define 和 const 常量
宏定义#define | const常量 |
相当于字符替换 | 常量声明 |
预处理器处理 | 编译器处理 |
无类型安全检查 | 有类型安全检查 |
不分配内存 | 分配内存 |
存储在代码段 | 存储在数据段 |