色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > C和C++中const的用法比較

C和C++中const的用法比較 時間:2018-09-26      來源:未知

在C語言中,通常使用#define來定義常數,其后在使用該常數的地方利用定義的宏名來進行常數替換,這樣可以避免在程序中到處出現magic numbers的亂象,并且#define是宏定義,不需要為其分配存儲空間。但是#define是在預處理器的控制范疇內,只能簡單地進行文本替換,不能進行類型安全檢查,并且其作用域從#define定義點開始,直到該編譯單元結束,無法進行較好的控制。

在C語言中,如果想讓編譯器進行constant folding,即在編譯時,通過計算將復雜的常數表達式化簡為一個值,通常只能用#define來進行(C99標準之前)。編譯器將始終為const變量分配存儲空間。const僅僅意味著定義的變量是只讀的,其值不能被修改。C編譯器不能將const作為一個編譯時的常數來使用,而總是為其分配存儲空間。因此如下定義全局數組

const int bufsize = 100;

char buf[bufsize];

盡管看起來符合我們的思維習慣,但編譯將出現錯誤。因為bufsize占有存儲空間,C編譯器在編譯期間不能確定它的值。

因此在C語言中,const并不是非常有用的。如果你想在一個常數表達式中使用一個符號名(也就是說必須在編譯時確定其值的話),C幾乎限定你只能使用預處理器的#define來進行。

在C中const是外連接的,不能將其定義放在頭文件中。如果用const int bufsize;的話,可以表示一個聲明(bufsize在別處定義,跟使用extern const int bufsize;是等價的),也可以表示一個定義(如果在連接時,其它地方都沒有定義的話,將其初始化為0)。

針對C中const的上述局限性,C++作出了重大的改進。在C++中,可以使用const來定義常數,因為const在編譯器的控制范疇內,而非由預處理器控制,所以可以進行類型安全檢查,也方便進行作用域控制。

在C++中可以利用const來消除#define定義常數的方式,以提高安全性。通常C++編譯器并不為const分配存儲空間,而是將其定義保存在符號表中,當使用時進行簡單的常數替換(像#define一樣不占空間,但擁有類型安全檢查和作用域控制)。因此上述不能編譯通過的C代碼,在C++中可以順利地通過。當不需要分配空間時(這依賴于數據類型的復雜度和編譯器的智能化程度),在類型安全檢查之后,像#define一樣,為了更高的效率,值將會被折疊進代碼中。

因此在C++中,當使用const時并不一定意味著會分配存儲空間,是否會分配空間要看是怎么使用的。通常編譯器會盡力避免為其分配空間,以通過constant folding來提高效率。常見的C++將會為const變量分配存儲空間的情況是:當取了某個const變量的地址時。注意通過引用來進行函數參數傳遞也是會取變量地址的,盡管從語法上看這并沒有取地址,但是應該清楚引用在底層實現上也是通過傳遞地址的方式來進行的。當不得不為const變量分配空間時,C++仍然能通過一定的手段來盡量進行constant folding。如下代碼所示:

const int i = 100; //典型的常數

const int j = i + 10; //從常數表達式得到值

long address = (long)&j; //因為取地址,強迫編譯器為j分配存儲空間

char buf[j+10]; //j+10仍然是一個常數表達式

當不得不為const分配空間時(與#define相對的別一種用法),const代表該空間在其后是只讀的,所以在定義時必須初始化,因為之后已經無法進行賦值以改變其內容。

在聚合數據類型上使用const也是可以的,但是編程者必須明白編譯器很可能并沒有智能到能將聚合類型保存在符號表中并進行constant folding的程度,所以需要為其分配存儲空間。這種情況下const的意義只是告訴編譯器,這是一小片不能被改變值的存儲區域。因此編譯器在編譯時不能確保其常量性

const int i[] = { 1, 2 ,3 ,4 };

//float f[i[3]]; //非法

struct S { int i, j; };

const S s[] = { { 1, 2 },{ 3, 4 } };

//double d[s[1].j]; //非法

以上兩行非法代碼都是因為在定義數組長度時,必須在編譯時確定常數值,但是因為對復雜的const對象會分配存儲空間,所以編譯時不能完全確定其值。

在C++中,在函數外定義的const是文件作用域的,所以可以將const的定義放在頭文件中。也就是說const在C++中是內連接的,不會在多個編譯單元之間發生沖突。如果想聲明在別的地方定義過的const變量,必須明確地用extern const int bufsize;(這是聲明)。而在定義處必須顯示地指定為外連接,extern const int bufsize=100;(注意這是定義,而非聲明,所以要初始化,這是區別于聲明的標志)

綜上所述,作為一條實踐準則,如果你確定某個值在其生命周期內你不會修改它,即對你而言是只讀性質的話,你就應該使用const來加以修飾。這不但能避免其無意中被修改,也能使編譯器通過不為其分配存儲空間、減少讀內存的次數等手段來產生更有效率的代碼。

從本文可以看出,C和C++中const的用法和含義有許多細微的不同之處。const在指針、函數參數、返回值、類對象、成員函數等地方都有應用,在這些情況下它們都有著不能被改變之意,但運用細節又各有其特點。

上一篇:Shell腳本編程——for循環

下一篇:C語言實現類繼承多態封裝

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 欧美黑人XXXX高潮猛交 | 亚洲精品国产黑色丝袜 | 激情婷婷丁香五月色综合 | 国产亚洲综合av | 亚洲爆乳大丰满无码专区 | 67149中文无码久久 | 天天爽夜夜爽夜夜爽精品视频 | 日本添下边视频全过程 | 狠狠色噜噜狠狠狠狠888奇米 | 男女啪啪高潮激烈免费版 | 麻豆果冻传媒精品国产av | 插曲视频免费高清观看 | 涩涩视频在线 | 日韩精品av无码一区二区三区 | 黑人上司好猛我好爽中文字幕 | 黄色在线免费播放 | 成在人线AV无码免费看网站 | 免费国产污网站在线观看 | 程视频精品视频一区二区三区欧 | 国产精品69人妻我爱绿帽子 | 国产精品aⅴ久久久久久鸭绿欲 | 亚洲综合熟女久久久30p | 亚洲制服丝袜一区二区三区 | 男女性色大片免费网站 | 四虎成人精品无码 | 又粗又硬进去好爽A片视频野花 | 亚洲第一极品精品无码 | 欧美综合日韩 | 无码性午夜视频在线观看 | 夜夜香夜夜摸夜夜添视频 | 自偷自拍亚洲综合精品第一页 | 韩国久久久久久级做爰片 | 人妻少妇无码中文幕久久 | 免费人妻精品一区二区三区 | 亚洲男人AV天堂午夜在 | 少妇熟女天堂网av | 性动态图AV无码专区 | 亚洲AV无码成人YELLOW | 亚洲日韩国产一区二区三区在线 | 免费A级毛片无码A∨蜜芽按摩 | 麻豆亚洲AV成人无码久久精品 |