C++入门——const的作用

本文详细介绍了C++中的const关键字,包括其作用于变量、函数参数、返回值、类的成员变量和成员函数等方面,阐述了const在类型检查、程序健壮性和效率提升上的优势。同时,对比了C++和C语言在处理const常量时的区别,并讨论了常引用与普通引用的不同。此外,还提到了在不同场景下使用const关键字的必要性。
摘要由CSDN通过智能技术生成

const的作用

  1. 定义变量(局部变量或全局变量)为常量,常量值不能被修改。且常量在定义时必须初始化

  2. 修饰函数的参数,表示在函数体类不能修改这个参数的值

  3. 修改函数的返回值

1)如果const修饰的返回值为指针,那么函数返回值(即指针)的内容是不能被修改的,而且这个返回值只能赋给被const修饰的指针。例如:

const char * GetString(); //定义一个函数
char *str = GetString(); //错误,因为str没有被const修饰
const char *str = GetString(); //正确

2)如果const修饰的返回值为引用,那么这个函数调用表达式不能被作为左值使用。例如:

const int & minus(int &i, int &j); //定义函数的返回值为const引用
minus(a, b) = 4; //错误,因为minus的返回值不能作为左值

3)如果用const修饰普通的返回值,由于这个返回值是一个临时变量,在函数调用结束后这个临时变量的生命周期就结束了,因此把这些返回值修饰为const是没有意义的。

  1. 修饰类的成员变量。表示这个成员变量只在某个对象生存周期内是常量,而对于整个类而言,却是可变的。因为一个类可以创建多个对象,不同的对象其const成员变量可以有不同的值。因此,const成员变量不能在类声明中初始化。例如:
class A
{
    const int size; //正确
    const int height = 170; //错误,const成员变量不能在类声明中初始化
};
  1. 修饰类的成员函数。那么这个函数就不能修改对象的成员变量

使用const的优点

  1. 进行类型检查,使编译器对处理内容有更多的了解,消除了一些隐患。例如,void f(const int n){},编译器就会知道n是一个常量,不允许被修改。

  2. 避免意义模糊的数字出现,方便进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变。

  3. 保护被修饰的东西,防止被意外修改,增强了程序的健壮性。

  4. 为函数重载提供参考。例如:

class A
{
    void f(int i){} //定义一个函数
    void f(int i) const {} //重载函数f,对象被定义为const时调用这个函数
};

通常,只有const对象才调用const方法;而非const对象会调用非const方法。

  1. 节省空间,避免不必要的内存分配。

从汇编的角度看,const定义常量知识给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一个复制品,而#define定义的常量在内存中有若干个复制品。

  1. 提高了程序的效率。编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储和读内存的操作,它的效率也很高。

什么情况下需要使用const关键字

  1. 修饰一般变量。一般变量指简单类型的常量。这种常量在定义时,修饰符const可以在类型说明符前,也可以用在类型说明符后。例如:int const x = 2;const int x = 2;

  2. 修饰常数组。定义或说明一个常数组可以采用如下格式:

int const a[3] = {1, 2, 3};
const int a[3] = {1, 2, 3};
  1. 修饰常对象。常对象是指对象常量,定义格式如下:
class A;
const A a;
A const a;

定义常对象时,同样要进行初始化,并且该对象不能再被更新。

  1. 修饰常指针。
const int *p; //const修饰int,说明p可变,p指向的int变量的值不可变
int const *p; //const修饰*p(*p也是int变量)。p可变,p指向的int变量的值不可变
int *const p; //const修饰指针p,p的指向不可变,p指向的对象可变
const int *const p; //指针p的指向和p指向的对象都不可变
  1. 修饰常引用。被const修饰的引用变量为常引用,一旦被初始化,就不能再指向其他对象了。

  2. 修饰函数的常参数。

  3. 修饰函数的返回值。表明该返回值不可被改变。

  4. 修饰类的成员变量。

  5. 在另一连接文件中引用const常量。使用方式:

extern const int i; //正确
extern const int j = 10; //错误,因为常量不可以被再次赋值。

常引用与普通引用有什么区别

一般引用的初始化表达式必须是左值,而常引用初始化表达式可以是右值。例如:

int& Ref = 10; //错误,因为10不是左值
const int& Ref = 10; //正确

C++和C语言的编译器在处理const的时候有什么不同

C++

C++中使用const定义了一个常量后,并不会为这个常量分配空间,而是将这个常量值写入符号表中,这使得它成为一个编译期间的常量,没有存储与读内存的操作。在编译过程中若发现使用常量,则直接以符号表中的值替换;为了兼容C语言,编译过程中若发现对const使用了extern或者&操作符,则给对应的常量另外分配存储空间。

但是,当使用&去取这个常量的地址时,编译器会分配一个空间给这个变量,但之后这个变量的值仍旧从符号表中读取,不管这个变量的存储空间中的值如何变化,都不会对这个常量的值产生影响。例如:

const int n = 10;
int* p = (int*)(&n);
*p = 20;
cout << n << endl; //输出10,符号表中的值,这个值在程序运行的过程中保持不变
cout << *p << endl; //输出20,读取为n分配的一个临时存储空间中的值,这个值可以被修改
C语言

C语言编译器则不同,当使用const定义一个常量的时候,编译器会直接开辟一个内存空间来存储该常量,每次存取的时候都是从这个内存空间中存取,因此可以取得const变量的地址,然后用这个地址来间接地修改const变量。例如:

const int n = 10;
int* p = (int*)(&n);
*p = 20; //间接修改了const变量n的值
printf("%d\n", n); //输出20
printf("%d\n", *p); //输出20

正因为如此,在C语言中如果使用下面的方式来定义数组,那么编译器会报错。

const int n = 10;
int arr[n]; //gcc编译器会认为n是一个变量,而数组的长度必须是常量,因此编译器会报错
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值