官术网_书友最值得收藏!

2.5 const常量

2.5.1 常量的定義

變量實質上是在程序運行過程中其值可以改變的內存單元的名字。常量就是在程序執行過程中其值固定不變的內存單元的名字。在C++中,常用const修飾符定義常量,方法如下:

const 常量類型 常量名=常量值;

例如:

const i=10;           //L1
const int i=10;          //L2
const char c='A';         //L3
const char s[]="C++ const !"; //L4

語句L1和L2等價,C++將沒有指定類型的常量定義默認為int類型(在Visual C++ .NET中不允許默認值,L1是錯誤的),L3定義了字符常量c,L4定義了字符常量數組s。

說明:① const常量必須在定義時初始化,且常量一經定義就不能修改(常量名不能出現在賦值符“=”的左邊),例如:

const int n;          //錯誤,常量n未被初始化
const int i = 5;         //定義常量i
i = 10;            //錯誤,修改常量
i++;             //錯誤,修改常量

② 在C++中,表達式可以出現在常量定義語句中。如果定義的常量是整型,則類型關鍵字int可以省略。例如:

int j,k=9;           //L1
const i1=10+k+6;        //L2
const int i1=10+k+6;      //L3
const i2=j+10;         //L4

當常量定義語句中出現表達式時,C++將首先計算表達式的值,然后把計算結果指定給常量。語句L2省略了類型關鍵字int,它與L3是完全等價的,相當于“const int i1=25;”。語句L4盡管在有的編譯環境下不會出錯誤,但沒有意義,因為j的取值是未知的。

③ 在C++中,仍然可以采用#define定義常量,但#define采用宏代換方式進行常量的處理,不具有類型檢查機制,存在不安全性。

2.5.2 const與指針

const可以與指針結合,由于指針涉及“指針本身和指針所指的對象”,因此它與常量的結合也比較復雜,可分為三種情況,如圖2-1所示。

圖2-1 const與指針的三種關系

圖2-1中的type代表C++中的任意數據類型,p是一個指針變量。其中,第一種是常量指針,即指針是常量,不能被修改,但其所指內存區域是變量,可修改;第二種是指向常量的指針,即指針是變量,可再指向其他內存單元,但其所指單元是常量,不能修改;第三種是指向常量的常指針,指針及其所指內存單元都為常量,皆不能被修改。

例2-7】 const與指針的關系。

//Eg2-7.cpp
#include <iostream.h>
int main(){
    char *const p0;    //L1  錯誤,p0是常量,必須初始化
    char *const p1="dukang";   //L2  正確
    char const *p2;    //L3  正確
    const char  *p3="dukang";   //L4  正確
    const char *const p4="dukang"; //L5  正確
    const char *const p5;       //L6  錯誤,p5是常量,必須初始化
    p1="wankang";   //L7  錯誤,p1是常量,不可改
    p2="wankang";   //L8  正確,p2是變量,可改
    p3="wankang";   //L9  正確,p3是變量,可改
    p4="wankang";   //L10 錯誤,p4是常量,不可改
    p1[0]='w';    //L11 正確
    p2[0]='w';    //L12 錯誤,*p2是常量,不可改
    p3[0]='w';    //L13 錯誤,*p3是常量,不可改
    p4[0]='w';    //L14 錯誤,*p4是常量,不可改
   return 0;
}

例中,*p2和*p3的定義形式等價,只是p2沒有初始化,p3被初始化了。請結合圖2-1和本例中的注釋理解各語句正確和錯誤的原因。

const對指針和變量之間的相互賦值具有一定影響:const對象的地址只能賦給指向const對象的指針,指向const對象的指針可以被賦予一個非const對象的地址,否則引起編譯錯誤。例如:

int x=9;     //L1
const int y=9;    //L2
int *p1;       //L3
const int *p2;     //L4
p1=&y;       //L5,錯誤
p2=&x;        //L6,正確

語句L5將引起編譯錯誤,若改為“p2=&y;”則是正確的,請結合上述說法理解其中原因。

2.5.3 const與引用

在定義引用時,可以用const進行限制,使它成為不允許被修改的常量引用。例如:

int i=9,
int &rr=i;
const int &ir=i;
rr=8;
ir=7;         //錯誤

最后一條語句是錯誤的,因為ir是const引用,不允許通過它修改對應的變量i。

const引用可以用常量初始化,但非const引用不能用常量初始化。例如:

int i=2;          //L1
const double &ff=10.0;   //L2
const int &ir=i+10;    //L3
int &ii=3;         //L4,錯誤

語句L4錯誤,語句L2、L3正確的原因與編譯器的處理方式有關。編譯器在實現常量引用時生成了一個臨時對象,然后讓引用指向這個對象。但該對象對用戶而言,是隱藏不可知的,不能訪問。例如,對于

const double &ff=10.0;

編譯器將其轉換為類似于下面的形式:

double temp=10.0;
const double &ff=temp;

編譯器首先產生不為用戶所知的臨時變量temp,然后將引用指向它。temp將保持到引用的生命期結束。

主站蜘蛛池模板: 闻喜县| 松溪县| 汪清县| 东海县| 芦山县| 东辽县| 临武县| 普安县| 夏邑县| 龙门县| 会理县| 都匀市| 梅州市| 盐源县| 富民县| 舞钢市| 黎川县| 广水市| 遂川县| 依兰县| 开原市| 清苑县| 砚山县| 崇明县| 武宁县| 肃宁县| 晋江市| 扎鲁特旗| 观塘区| 那曲县| 日照市| 大埔区| 巩义市| 怀柔区| 虞城县| 屏山县| 辽宁省| 讷河市| 蒙城县| 中超| 濮阳市|