C和C++中const的用法【修饰变量、修饰函数参数、修饰函数返回值、常函数、常对象】

目录

C语言中的用法

一、修饰普通变量

二、修饰指针

1. 常量指针:const int* 和int const * 

2.指针常量:int * const

三、修饰函数参数

四、修饰函数的返回值

C++中的用法

一、包括C语言的所有用法

二、修饰类的成员函数:常函数

三、修饰类的对象:常量对象 常对象

总结:


C语言中的用法

一、修饰普通变量

const int 和 int const在修饰普通的变量类型(除指针)作用是相同的。

如下a,b都是int型常量,不能被修改。

int const a=5;
const int b=10;

二、修饰指针

1. 常量指针:const int* 和int const * 

只要const位于*的左侧,无论它在类型名的左边或右边,都声明了一个指向对象的指针,叫做常量指针

	int a=10;
	int *q=&a;
	const int *p=&a;

定义一个变量a,q是一个普通的指向a的指针,p则是常量指针。这两者有什么区别呢?

普通指针q可以修改a,而对于指针p,不管他指向的是常量还是变量,在常量指针眼中都是常量,都是不可修改的。也就是说常量指针是不能修改指向对象的的指针。

常量指针的本质还是指针,可以指向任何变量或常量,也可以更改指向对象,但是不管指向谁,他都不能去修改那个指向对象的值。

2.指针常量:int * const

声明方式:

int a;
int* const p = &a; //const放在指针声明操作符的右侧

只要const位于指针声明操作符右侧,就表示声明的对象是一个常量,且它的内容是一个指针,也就是一个地址。

上面的声明可以这么读:声明了一个常量p,它的值是变量a的地址(变量a的地址就是指向变量a的指针)。

指针常量是一个常量,在声明的时候一定要赋初始值。一旦赋值,这个常量再也不能被修改。

指针常量可以通过本身的指针特性去修改指向的对象

指针常量是将一个常量(常量的值是地址)与一个对象锁定,一个指针常量绑定了一个对象后,就无法再更改,但是这个指针常量拥有和对象一样的权限,可以修改对象,也就是说他们现在合为一体了。其实这就是引用:引用的本质就是一个指针常量。

关于引用:https://blog.csdn.net/qq_21989927/article/details/107447970

推荐:指针常量、常量指针【const int和int const】【const int *和int const*和int* const】

三、修饰函数参数

1、防止修改指针指向的内容  【常量指针】

#include<iostream>
using namespace std;
 
void show_a_b(const int *a,int *b){
	a[1]=100;
	b[1]=100;
	for (int i=0; i<4; i++)
		cout<<a[i]<<" "<<b[i]<<endl;
}

int main() {
	int a[100]={1,2,3,4};
	int b[100]={1,2,3,4};
	show_a_b(a,b);
	return 0;
}

我们的本意是输出a,b数组的内容,不会通过指针来修改数组内容。同样是在中间不小心修改了数据,const修饰a,会查出错误报错,而b则不会,所以常量指针参数可以增强函数的健壮性。

2、防止修改指针指向的地址 【指针常量】

void swap ( int * const p1 , int * const p2 )

指针p1和指针p2指向的地址都不能修改。

 

四、修饰函数的返回值

如果函数的返回值是一个指针,我们希望这个返回值(指针)不能被修改,我们可以用常量指针的方法修饰函数返回值。

例如函数

#include<iostream>
using namespace std;

const int* add(int *a){
	*a=*a+10;
	return a;
}

int main() {
	int b=1000;
	int *p=&b;
	const int *q=add(p);  //调用
	cout<<*q<<endl;
	return 0;
}

如直接调用函数   int *q=add(p); 是错误的,会报错,因为程序认为你可能会通过q指针来修改返回值(指针)指向的数据。

正确的用法是: const int *q=add(p); 

样可以通过在函数返回值前加const来实现让函数调用时也必须加const,都成为常量指针,不能通过指针修改数据,进而保证了数据的安全。

另外,用指针常量修饰函数返回值是无意义的,因为函数返回时原来就是一对一的复制过程,不会改变指向对象。如下:x

int* const find();

 

C++中的用法

一、包括C语言的所有用法

        上述一二三四都包括。

二、修饰类的成员函数:常函数

const修饰类的成员函数,使其只能读取数据成员变量,不能改变数据成员变量。

如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const 成员函数,编译器将指出错误,提高程序的健壮性。所以,任何不会修改数据成员(即函数中的成员变量)的函数都应该声明为const 类型。

如以下程序中,类stack 的成员函数GetCount 仅用于计数,从逻辑上讲GetCount 应当为const 函数。

class Stack{ 
	public:
		void Push(int elem);
		int Pop(void);
		int GetCount(void) const; // const 成员函数
	private:
		int m_num;
		int m_data[100];
};
int Stack::GetCount(void) const{ 
	++ m_num; // 编译错误,企图修改数据成员m_num
	Pop(); // 编译错误,企图调用非const 函数
	return m_num;
}

const 成员函数的声明看起来怪怪的:const 关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。

 

三、修饰类的对象:常量对象 常对象

1.常对象只能访问成员变量的值,不能修改。

2.常对象只能调用常函数,不能调用其他成员函数。

3.用mutable修饰的数据成员,任何情况下都可修改。

#include<iostream>
using namespace std;

class Person {
public:
	Person() {
		m_A = 0;
		m_B = 0;
	}
	void ShowPerson() const {
		//this->m_A = 100; //const修饰成员函数,表示成员变量不能修改,除了mutable修饰的变量
		this->m_B = 666;
		cout<<"修改成功"<<endl;
	}
	void MyFunc(){
		cout<<"FUCK"<<endl;
	}
	int m_A;
	mutable int m_B; //可修改 可变的
};

int main() {
	const Person person; //常量对象  
	cout << person.m_A << endl;
	//person.m_A = 100; //常对象不能修改成员变量的值,但是可以访问
	person.m_B = 100; //但是常对象可以修改mutable修饰成员变量

	//常对象访问成员函数
	//person.MyFunc(); //常对象只能调用常函数
	person.ShowPerson();
	return 0;
}

 

总结:

对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。

对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。

若类的成员函数若不涉及修改成员变量,则最好用const修饰成员函数,以增加程序的健壮性。

凡希望保证数据成员不被改变的对象,可以声明为常对象。

mutable修饰的变量可以随意修改。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值