【C++】const关键字

本文详细比较了C和C++中const关键字的使用,包括全局和局部变量的常量特性、内存分配、不同数据类型的情况以及const在宏、命名空间和成员函数中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.C和C++的不同

1.1.C语言中特点
1 const int a = 10;//不要把a看成常量
2 //a的本质 是变量 只是 只读变量

a、c语言的const修饰全局变量 默认是(外部链接的)

//c语言的const修饰全局变量 默认是(外部链接的)
//外部链接:其他源文件 可以使用
const int num = 100;//只读的全局变量 内存放在文字常量区(内存空间只读)
//对fun.c中的num进行声明(不要赋值)
extern const int num;

void test03()
{
	printf("num = %d\n",num);
	//num = 200;//err num只读

	//C语言中const 修饰变量名 说明变量名为只读(用户不能通过变量名data进行赋值)
	const int data = 100;//局部只读变量 内存在栈区(内存可读可写)
	//data = 200;//err

	printf("data = %d\n",data);
	//但是:如果知道data的地址 可以通过地址间接的修改data所对应空间的内容
	int *p = (int *)&data;
	 *p = 2000;
	printf("data = %d\n",data);//ok 200
	}

总结:

在c语言中

1、const修饰全局变量num 变量名只读 内存空间在文 字常量区(只读)、不能通过num的地址 修改空间内容

2、const修饰局部变量data 变量名只读 内存空间栈区 (可读可写),可以通过data地址 间接的修改空间内容

1.2 c++中的const 深入理解

//const修饰的全局变量 默认是内部链接(只在当前源文件有效 不能直接用于其他源文
件)
//const int num = 100;
//如果必须用在其他源文件 使用只读的全局变量 必须加extern将num转换成外部链接
extern const int num = 100;
//声明
extern const int num;
struct Person
{
    int num;
    char name[32];
};
 void test04()
{
     cout<<"全局num = "<<num<<endl;//err 不识别num
    
    //1、c++中 对于基础类型 系统不会给data开辟空间 data放到符号表中
    const int data = 10;
    //data = 100;//err 只读
    cout<<"data = "<<data<<endl;
    //2、c++中当 对data 取地址的时候 系统就会给data开辟空间
    int *p = (int *)&data;
     *p = 2000;
    cout<<"*p = "<<*p<<endl;//空间内容修改成功 2000
    
    cout<<"data = "<<data<<endl;//data 还是10为啥?
    
    //2、当以变量的形式 初始化 const修饰的变量 系统会为其开辟空间
    int b = 200;
    const int a= b;//系统直接为a开辟空间 而不会把a放入符号表中
     p = (int *)&a;
     *p = 3000;
    cout<<"*p = "<<*p <<endl;//3000
    cout<<"a = "<<a <<endl;//3000
    
     //3、const 自定义数据类型(结构体、对象) 系统会分配空间
     const Person per = {100,"lucy"};
     //per.num = 1000;//err
     cout<<"num = "<<per.num<<", name = "<<per.name<<endl;//100 lucy
    Person *p1 = (Person *)&per;
    p1‐>num = 2000;
    cout<<"num = "<<per.num<<", name = "<<per.name<<endl;//2000 lucy
}

总结:c++总结

1、const int data = 10;//data先放入符号表

2、如果对data取地址 系统才会给data开辟空间

3、const int a = b;//b是变量名 系统直接给a开辟空间 而 不放入符号表

4、cosnt 修饰自定义数据 系统为自定义数据开辟空间

1.3 尽量const替换#define

1、宏没有类型 const有

#define MAX 1024
const short my_max =1024;
void func(short i)
{
	cout<<"short函数"<<endl;
}
void func(int i)
{
    cout<<"int函数"<<endl;
 }
void test05()
{
    func(MAX);//int 函数
    
    func(my_max);//short函数
}

2、宏的作用域是整个文件 const的作用域 以定义情况决定

 void my_func(void)
{
	//作用范围 是当前复合语句
	const int my_num = 10;

	//作用范围 当前位置 到文件结束
	#define MY_NUM 10
}
void test06()
{
    //cout<<"my_num = "<<my_num<<endl;//err 不识别
    cout<<"MY_NUM = "<<MY_NUM<<endl;//ok 能识别
 }

3、宏不能作为命名空间的成员 const可以

namespace A 
{
	// const可以作为成员
	const int my_a=100;

	//MY_A 属于文件 不属于A
	#define MY_A 200
}
void test07()
{
    cout<<"my_a = "<<A::my_a<<endl;
     //cout<<"MY_A = "<<A::MY_A<<endl;//err
     cout<<"MY_A = "<<MY_A<<endl;
}

2. const修饰成员函数

const修饰的成员函数,表示常成员函数,特性如下:

● 可以调用成员变量,但是不能修改成员变量的数值。

● 不能调用非const的成员函数,哪怕这个函数没有修改成员变量。

建议只要成员函数不修改成员变量就是用const修饰,例如show显示等函数:

#include <iostream>
using namespace std;


class Demo
{
    private:
    int a;
    public:
Demo(int a)
{
    this->a = a;
}

void func0()
{
    cout << "哈哈哈哈哈" << endl;
}

// const修饰成员函数
int get_demo() const
{
    return a;
}

void test() const
{
    //        a++; // 错误,const修饰的成员函数,不能修改成员变量
    //        func0(); // 错误,const修饰的成员函数,不能调用非const修饰的成员函数
    cout << a << endl;
    get_demo(); // 常成员函数,可以调用类内的常成员函数
}

};

int main()
{
    Demo demo(1);
    cout << demo.get_demo() << endl;
    demo.func0();
    demo.test();

    return 0;
}

3 .const修饰对象

const修饰的对象被称为常量对象,这种对象的成员变量值无法被修改,也无法调用非const的成员函数。

#include <iostream>
using namespace std;


class Demo
{
private:
int a;
public:
int b = 20;

Demo(int a)
{
    this->a = a;
}

void func0()
{
    cout << "哈哈哈哈哈" << endl;
}

// const修饰成员函数
int get_demo() const
{
    return a;
}

void test() const
{
    //        a++; // 错误,const修饰的成员函数,不能修改成员变量
    //        func0(); // 错误,const修饰的成员函数,不能调用非const修饰的成员函数
    cout << a << endl;
    get_demo(); // 常成员函数,可以调用类内的常成员函数
}

};

int main()
{
    //    const Demo demo(1);
    Demo const demo(1); // 两种初始化的方式,等效于上一行。

    cout << demo.get_demo() << endl;

    //    demo.func0(); // 错误,const修饰的对象,无法调用非const成员函数
    demo.test();

    //    demo.b = 10; // 错误,const修饰的对象,无法修改成员变量
    cout << demo.b << endl; // 可以调用,但是无法修改

    return 0;
}

4. const修饰成员变量

const修饰的成员变量被称为常成员变量,表示改成员变量的值无法被修改。

常成员变量有两种初始化的方式:

● 直接赋值

● 构造初始化列表

上述两种方式同时使用时,前者失效,以后者为准

#include <iostream>
using namespace std;


class Demo
{
private:
    // const 修饰成员变量
    const int a = 1;
    const int b = 2;
    const int c = 3;

public:

Demo(int a,int b, int c):a(a),b(b),c(c){}

void show()
{
    cout << a << " " << b << " " << c << endl;
}


void test()
{
    //        a++; // 错误,常成员变量,只能调用,无法被修改
    //        b++;
    //        c++;
}

};

int main()
{
    Demo d(10,20,30);
    d.show();
    d.test();
    return 0;
}

5. const修饰局部变量

const修饰局部变量,表示该局部变量不能被修改。

这种方式常用于引用参数。

#include <iostream>
using namespace std;


class Demo
{
private:
    // const 修饰成员变量
    const int a = 1;
    const int b = 2;
    const int c = 3;

public:

Demo(int a,int b, int c):a(a),b(b),c(c){}

void show()
{
    cout << a << " " << b << " " << c << endl;
}


void test(const int &i)
{
    //        i = 3; const修饰参数,常用于引用参数,方式函数内部对外部参数进行修改
    cout << i << endl;
    const int e = 1;
    //        e = 2; // const修饰的局部变量,可以使用,但是无法修改。
    cout << e << endl;
}

};

int main()
{
    int i = 2;
    Demo d(10,20,30);
    d.show();
    d.test(i);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值