C/C++经典面试题1,const关键字用法总结


  本文主要说明了const关键字的作用,包括了用于对数组,指针与类相关的修饰方法,作为笔记总结使用。若有错误与不足,欢迎指正。

const关键字

  用于修饰一个常类型,常类型的变量或对象的值无法被改变,即无法作为左值,因此在定义时必须进行初始化

const修饰范围

  • 修饰变量与对象,使其成为一般常量与对象常量
  • 修饰函数的参数与返回值
  • 修饰成员函数的函数体,指类的成员函数

const使用方法

修饰变量与对象

应当注意,除去指针类型,<类型> const与const <类型> 实质都为const <类型>。

但是,例如  int* const 和 const int* 不同,下面会讲解。

  • 修饰常用变量
const int a = 2;
const double b = 1.23;
const bool c;//错误,c需要设定初始值
//int const 与 const int 并无本质区别,实质都是const int

  • 修饰引用
const int a = 2;
//int &b = a;错误,引用常量时,变量本身也要用const修饰
const int& b = a;
b = 3;//错误,const修饰当然不能为左值
  • 修饰数组,注意数组中的元素被修饰为const,不能作为左值
const int a[4] = { 1,2,3,4 };
const int b[2][2] = { {1,2},{3,4} };
//int const也一样,以下语句错误,数据元素被修饰为const,不能为左值
a[3] = 1;b[0][0] = 3;
  • 修饰指针

  注意指针常量与常量指针的区别

  指针常量:不能通过指针来修改变量的值

  常量指针:一直指向该变量,不能给该指针赋予其他地址

const <指针类型>

int a = 2;//最好使用const修饰,否则会被修改与目的不符
const int *p1 = &a; //int const *p1=&a也一样
int *p2 = &a;
//*p1 = 3;//错误,*p1为指针常量,不能为左值
p1 = p2;//OK,指针本身可以作为左值
a = 4;//虽然无法通过*p1改变值,但可以直接改变a的值,不推荐。

<指针类型> const

int a = 2, b = 3;    
int* const p1 = &a;
int *p2 = &b;
p1 = p2;//错误,p1为常量指针,该指针本身不能为左值
*p1 = 3;//OK,指针指向的变量可以为左值
  • 修饰指针数组与数组指针

数组指针与指针数组简介

int myarray[4] = { 1,2,3,4 };
int *p1 = 0, *p2 = 0;
int* a[2] = { p1,p2 };//a是一个指针数组,数组中元素全部是 int* 类型的指针
int(*b)[4] = &myarray;//b是一个数组指针,b指向一个大小为4的数组
//由于b是一个指向大小为4的数组的指针,首先得到指向的数组:*b,再访问其元素(*b)[pos]
cout << (*b)[1] << " " << a[1];

const修饰

int myarray[4] = { 1,2,3,4 };
int *p1 = 0, *p2 = 0;
const int* a[2]{ p1,p2 };
*a[0] = 0;//错误,数组中元素为指针常量,其指向的变量不能为左值
a[0] = 0;//OK,指针本身可以作为左值
int* const b[2]{ p1,p2 };
b[0] = 0;//错误,数组中元素为常量指针,指针本身不能为左值
*b[0] = 0;//OK,指针指向的变量可以为左值
const int(*b)[4] = &myarray;
b = &myarray;//错误,b本身为一个指向大小为4的数组的指针,被修饰为const,不能作为左值
  • 修饰对象与成员变量

 class Myclass
 {
 public:
     Myclass(int a,int b)
     {
         this->a = a;
         this->b = b;
     }
     int a;
     int b;
 };
const Myclass a(1,2);
a.a = 2;//错误,被const修饰的对象及其成员变量无法作为左值

注意修饰成员变量时,初始化构造函数必须写在构造函数初始化列表中,而不能写在构造函数体中

 class Myclass
 {
 public:
     Myclass(int x, int y)//错误,不能在函数体内初始化
     {
         this->a = x;
         this->b = a;
     }
     Myclass(int x,int y):a(x),b(a){}//OK在构造函数初始化列表中初始化
     const int a;
     const int &b;
     static const int sc;
 };
 const int Myclass::sc = 2;
  • 修饰类中重载函数
class Myclass
 {
 public:
     void print()
     {
         cout << "print";
     }
     void print() const
     {
         cout << "const print";
     }
 };
const Myclass a;
a.print();//const,const对象默认调用const重载函数
Myclass b;
b.print();//默认调用非const重载函数

修饰函数的参数与返回值

  • 修饰函数参数:被修饰的参数在函数体中生效,不同类型参数的作用在以上都可以找到

  若是此处为非指针与引用常量,都在函数中传递实参的副本,无论怎么改变都不会影响实际的值,因此不讨论。

  若是此处为指针或是引用常量,都是实参本身传递,需要考虑保护实参本身

 //保护实参本身不会被函数体修改
int mymax(const int& a, const int& b)
 {
     return a > b ? a : b;
 }
//没有保护
int mymin(int *a, int *b)
{
    return *a > *b ? *b : *a;
}

int a = 2, b = 3;
const int *p1 = &a, *p2 = &b;
cout << mymin(p1, p2);//错误,*p1,*p2不能作为左值,而在mymin函数体中可能会被改变
  • 修饰函数返回值
const char* getString();
char  *str=getString();//错误,getString返回值被修饰为const
const char *str=getString();//OK

修饰成员函数的函数体

const放在类成员函数的尾部,用于修饰该成员函数,函数体内不能让类的成员变量作为左值

 class Myclass
 {
 public:
     int getval() const
     {
         this->val = 2;//错误,不能改变类的成员变量
         return this->val;
     }
 private:
     int val;
 };

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM