C的const用法总结
普通变量类型
const int a;
int const a;
测试代码
#include <stdio.h>
int main()
{
const int a = 1;//需在声明时赋初始值,等价于int const a = 1;
printf("a=%d\n", a);
int c = *(int*)&a = 2;
printf("a=%d c=%d\n\n", a, c);
//printf("可以注意到a的值没有发生改变");
return 0;
}
VS2019运行结果
结论
const int a = 1;
与int const a = 1;
等效- 应该在声明时就进行初始化
- 若不创建新的变量,只是强制类型转换并赋值,不会改变a的值。
指针类型
const int *p;
#include <stdio.h>
int main()
{
int a = 1, b = 2;
const int* p = &a;
printf("p=%x &a=%x\n", p, &a);//输出地址应该相同
//a的值可以改变
a = 4;
printf("a=%d\n", a);
//*p的值不能改变
//*p = 5;//此条语句编译时不予通过
//p的指向可以改变
p = &b;
printf("p=%x &b=%x\n", p, &b);//输出地址应该相同
return 0;
}
VS2019运行结果
当*p = 5;这条语句没有被注释时,
结论
- 对于
const int* p;
,可以改变p的值,但不能改变*p的值,即可以改变p所存储的地址值,但不能通过改变*p来改变p所指对象的值。
int* const p;
#include <stdio.h>
int main()
{
int a = 1, b = 2;
int* const p = &a;//常量变量p需要在声明时进行初始化
printf("*p改变前:\n*p=%d a=%d\n\n", *p, a);
*p = 3;//改变*p的同时,将a也改变了
printf("*p改变后:\n*p=%d a=%d\n", *p, a);
//p的值不可改变
//p = &b;//若此条语句未被注释掉,则编译不通过
return 0;
}
VS2019运行结果
当p = &b;这条语句没有被注释时,
结论
- 对于
int* const p;
,可以改变*p的值,但不能改变p的值,且*p的改变伴随着p所指变量值的改变。
const int* const p;
#include <stdio.h>
int main()
{
int a = 1, b = 2;
const int* const p = &a;
*p = 3;//编译器报错:表达式必须是可修改的左值
p = &b;//编译器报错:表达式必须是可修改的左值
return 0;
}
理解记忆的窍门
易混淆的其实就是两个指针类型int* const p;
和const int* p;
可以通过观察const修饰的是什么来加以区分。
int* const p;
中,const后紧接p,所以p是不能改变的;而
const int* p;
中,const后接的是整个int* p
,而int* p
代表的就是p所指对象,即表明p所指对象不能改变。
所以说了这么多,最关键的还是一点,即被const修饰的内容不可更改,是有内存的只读变量!
C++与C语言const的一点区别
//c语言中的const是一个冒牌货,可以被指针间接修改
//c++中const是一个真正的常量,不能被修改
int main()
{
//好像a是一个常量,但其实不是
const int a = 10;
int *p = (int*)&a;
printf("a=%d\n", a);
*p = 11;//间接赋值,c语言会赋值成功,c++赋值不成功
printf("a=%d\n", a);
return 0;
}
c的结果:
a=10
a=11
c++的结果:
a=10
a=10
C++中const在修饰类中和非类中变量时的差别
今天突然发现一个让我感到很疑惑的点,暂时不知道为什么,先记在这里,等考试周过了再来研究一下原因。
#include <iostream>
using namespace std;
class A {
const int a;
public:
A(int size);
~A();
void qi();
};
A::A(int x) : a(x){}
A::~A(){}
void A::qi()
{
cout << "a在类中声明" << endl;
cout << "修改前:a = " << a << endl;
*(int*)&a = 10;
cout << "修改后:a = " << a << endl;
cout << "修改成功!" << endl;
}
int main()
{
A a(5);
a.qi();
const int b = 3;
cout << endl << "b在类外" << endl;
cout << "修改前:b = " << b << endl;
*(int*)&b = 6;
cout << "修改后:b = " << b << endl;
cout << "修改失败!" << endl;
return 0;
}
下面这张图非本人的,在别人那儿截取的,先放这里。侵删
理论上如此,但可以当作数据成员的默认值。