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