天天看點

C++:18---const關鍵字(附常量指針、指針常量、常量指針常量)

一、const變量的一些基本特點

  • ①const修飾的變量不能被修改
  1. const int a=10;
  2. a=20;//錯誤
  • ②因為const修飾的變量不能被修改,是以必須被初始化
  1. int a=10;
  2. const int b=a; //正确
  3. const int c=10; //正确
  • ③const修飾的變量可以指派給其他值
  1. const int a=10;
  2. int b=a;//正确
  • ④可以有常量引用
  1. int a=10;
  2. const int &b=a;

二、在其他檔案中使用const常量(extern)

  • const常量預設隻能在目前檔案使用,可以使用extern使const常量在檔案中共享
  • 注意:在别的檔案中使用const常量時,如果出現同名時:①其他檔案的局部變量會覆寫const常量。②其他檔案的全局變量會報錯,顯示重定義

方法:

  • 在demo.h檔案中extern const int a;//聲明
  • 在demo.c檔案中extern const int a=1;(extern可省略)

三、const和引用

  • 把引用綁定到const對象上,就像綁定到其他對象上一樣,我們稱之為“對常量的引用”
  • 與普通的引用不同的是,對常量的引用不能被用作修飾它所綁定的對象:
  1. const int ci = 1024;
  2. const int &r1 = ci; //正确,引用到常量上
  3. r1 = 42; //錯誤,不能對常量的引用進行修改
  4. int &r2 = ci; //錯誤,不能讓一個非常量引用指向一個常量對象
  5. //因為引用可以通過改變自身值而改變所引用的值,是以為了防止引用改變值,禁止使用普通引用引向const常量

初始化和對const的引用

  •  在引用的文章中介紹,引用的類型必須與其引用的對象類型一緻,但是有兩個例外:
  • ①在初始化常量引用時允許用任意表達式作為初始值,隻要該表達式的結果能轉成引用的類型即可(見下面代碼段1)
  • ②允許為一個常量引用綁定非常量的對象、字面值、甚至是個一般表達式(見下面代碼段2)
  1. //代碼段1
  2. double dval = 3.14;
  3. const int &ri = dval;//正确
  4. /*
  5. 上面的代碼會生成一個int類型的臨時變量,然後将臨時變量指派給ri,是以上述代碼可以擴充為:
  6. double dval = 3.14;
  7. const int temp = dval; //臨時變量
  8. const int &ri = temp ;
  9. */
  1. //代碼段2
  2. int i = 42;
  3. const int &r1 = i; //正确,允許将const int&綁定到一個普通對象上
  4. const int &r2 = 42; //正确
  5. const int &r3 = r1 * 2;//正确
  6. int &r4 = r1 * 2; //錯誤

四、常量和指針

  • 也可以用const來修飾指針,指向常量的指針不能用于改變其所指對象的值
  • 常量隻能由常量指針來指向,不能由非常量指針來指向
  1. const double pi = 3.14;
  2. double *ptr = π //錯誤。ptr是非常量的
  3. const double *cptr = π//正确
  • 可以使用常量指針指向一個非常量對象:
  1. double dval = 3.14;
  2. const double *cptr = &dval; //正确
  • 不能通過常量指針改變所指對象的值:
  1. const double dval = 3.14;
  2. const double *cptr = &dval; //正确
  3. *cptr = 6.28; //錯誤
  4. double dval2 = 3.14;
  5. const double *cptr2 = &dval; //正确
  6. *cptr2 = 6.28; //錯誤

五、常量指針、指針常量、常量指針常量

  • 常量指針:(指向常量的指針)。指向可以改,但是不能通過該指針改變所指向的值
  • 這種類型的const也被稱為“底層const”:表示指針所指向的值是個常量
  • 指針常量:(指針的常量)。指向不可以改,但可以通過該指針改變所指向的值
  • 這種類型的const也被稱為“頂層const”:表示指針本身是個常量
  • 常量指針常量:不可以修改指向,也不可以修改所指向的值
  1. const int* pa; //常量指針
  2. int const* pb; //常量指針
  3. int * const pc; //指針常量
  4. int const* const pd;//常量指針常量

如果通過const的位置來判斷const對什麼起作用:

  • const對左邊的類型起作用,當const左邊沒有東西時,才對右邊的起作用,是以有以下規則:
  • 常量指針時,const左邊為int或const左邊無内容右邊有int,是以隻對int(值)生效,是以為常量指針
  • 指針常量時,const左邊為*(代表指針),是以為指針常量
  • 常量指針常量時,有兩個const,對int(值),*(指針)都生效,是以為常量指針常量
  • 當然,上面的規則可以簡化為下面一句話:
  • const出現在“*”号的左邊,代表所指之物是常量
  • const出現在“*”号的右邊,代表指針自身是個常量

初始化與使用

  • 常量指針,因為所指對象是個常量,是以有下面的規則
  • 可以常量指針指向于常量或非常量
  • 但是不能修改值
  1. int a = 1;
  2. const int b = 2;
  3. const int *pa = &a; //正确,可以指向非常量
  4. pa = &b; //正确,指向可以改變
  5. *pa = 1; //不能通過常量指針修改所指對象的值
  • 指針常量,因為指針是個常量,而不是類型是常量,是以有下面的規則:
  • 隻能指向于非常量,不能指向于常量(因為放置指針常量修改常量的值)
  • 不可以改變指針常量的指向,因為指針自身是個常量
  1. int a = 1;
  2. const int b = 2;
  3. int c = 3;
  4. int* const pa = &a; //正确,a是非常量
  5. int* const pb = &b; //錯誤,b是常量
  6. *pa = 10; //正确,可以修改指向對象的值
  7. pa = &c; //錯誤,不能修改pa的指向(因為指針自身是個常量)
  • 常量指針常量,有如下規則:
  • 可以使用常量、非常量賦初值
  • 不能改變值、不能改變指向
  1. int a = 1;
  2. const int b = 2;
  3. const int *const p1 = &a; //正确
  4. const int *const p2 = &b; //正确
  5. *p1 = 2; //錯誤
  6. p1 = &b; //錯誤

之間的轉換

  • 轉換的規則是:非常量可以轉換為常量,反之不行
  1. int i = 0;
  2. int j = 0;
  3. const int ci = 42;
  4. const int *p2 = &ci;
  5. int *const p1 = &j;
  6. const int *const p3 = p2;
  7. p3 = p1; //錯誤,p3的指向也不能更改
  8. int *p = p3; //錯誤,p3包含const,而p沒有
  9. p2 = p3; //正确,p2和p3都包含底層const
  10. p1 = p3; //錯誤,p1的指向不能更改