C 使用之常量的定義

2021-09-26 03:24:28 字數 2568 閱讀 3877

在介紹c++的常前,先看下下面的**。

for (int i = 0; i < 512; ++i)
512是什麼,它具有什麼含義?在**中若直接使用類似512這些「魔數」(magic number),這些數字的具體含義就不能體現出來。另外,假如程式中多處包含512這個數,隨著時間的推移,發現有些512需要更改為1024,有些512需要保持不變。這種情況下,程式設計師必須小心謹慎地去乙個乙個地查詢程式中所有的512,並保證更改的數字不會出錯——使用「魔數」會導致難以維護的問題。

為了解決以上問題,可以使用#define預處理器指令來定義乙個常量。例如,

#define max_num_size 512

for (i = 0; i < max_num_size; ++i)

通過使用#define定義max_num_size這個巨集,可以清晰看到512的具體含義,另外,假如需要更改這個數字,只須直接修改#define一處就可以了。

然而,在c++中,並不提倡使用#define定義乙個常量。#define本質上是乙個預處理器指令,它僅僅表示使用乙個串代替別乙個串而已。也就是說,#define定義的常量從未被編譯器看到——它們在編譯器開始處理原始碼之前就被移走了。

具體來說,避免使用#define來定義常量,原因如下所述。

1. 沒有指定型別

#define不涉及為定義的常量做型別檢查,為了顯式地指定常量型別,需要在常量後加上字尾。比如,對於float型別的常量,在數字後面加上f字尾。

2. 沒有指定作用域

#define定義的常量是全域性的。

3. 沒有訪問控制

不能把#define定義的常量標記為公有的,受保護的,或者私有的,它本質上是公有的。

因為巨集一旦被定義,它就在其後的編譯過程中有效(除非在某處被#undef)。

4. 沒有符號

前面的例子中,巨集max_num_size可能會被預處理器從**中剝離,這樣,編譯器就無法看見這個名字。這樣,程式設計師在除錯時只能看到一些沒有任何描述性的常量值。

與使用#define定義常量相比,更可取的辦法是使用c++的const限定修飾符來定義常量。例如,對於max_num_size,可進行如下定義:

const int max_num_size = 512;
作為乙個整型常量,const修飾的max_num_size肯定被編譯器看到,當然會進入符號表。假如將max_num_size定義在某個類中,還可以對其實施訪問控制器和為其指定作用域。例如:

class gameplayer

;const int gameplayer:: max_num_size = 512;

在上述的**中,我們定義了乙個int型的常量,該常量的作用域為gameplayer類在,並標記為私有訪問,並且會進入符號表。

值得指出的是,要注意const定義常量在某種程式上可能會使**更臃腫。例如,在某個標頭檔案中定義的了以下的一些常量:

const int max_name_length = 128;

const float log_2e = log2(2.71828183f);

const std::string log_file_name = 「filename.log」;

在預設情況下,以這種方式定義的變數會促使編譯器為每個包含此標頭檔案的模組分配變數儲存空間。如果定義了很多常量,並且該標頭檔案被很多.cpp檔案包含,那麼會導致.o目標檔案和最終的二進位制檔案膨脹。

解決辦法是在標頭檔案中使用extern宣告常量:

// myconst.h

extern const int max_name_length;

extern const float log_2e;

extern const std::string log_file_name;

然後在相應的.cpp檔案中定義每個常量的值:

// myconst.cpp

const int max_name_length = 128;

const float log_2e = log2(2.71828183f);

const std::string log_file_name = 「filename.log」;

通過這種方式,變數的空間就只會分配一次。

使用extern來宣告的常量是全域性的,若要將常量的作用域限制在類中,則須在類中宣告常量,並將其宣告為static(這樣它們就不會計入每個物件的記憶體大小中)。

// myclass.h

class myclass

;

然後在相應的.cpp檔案中定義這些常量:

// myclass.cpp

const int max_name_length = 128;

const float log_2e = log2(2.71828183f);

const std::string log_file_name = 「filename.log」;

當然,在某些情況下,使用列舉型別代替常量也可以避免檔案空間膨脹的問題。

C 常量的定義

1 巨集定義 define demo 10 這種方式定義的常量,在編譯時,編譯器看不到demo這個名稱,在預處理的時候都被替換了。於是demo沒有進入符號表內,這樣,在運用此常量的地方出現編譯錯誤時,錯誤資訊不會提到demo,會導致難以定位錯誤資訊。另外在進行除錯時,也看不到demo名稱。2 con...

React JSX 常量定義與使用

user是定義資料 const user 格式化資料 function formatname user 拼裝資料 const element 渲染資料 reactdom.render element,document.getelementbyid root 1.對於const表示constant的簡...

nf hook ops中使用常量定義

supported address families define af unspec 0 define af unix 1 unix domain sockets define af local 1 posix name for af unix define af inet 2 internet ...