承接c++:生存期、作用域和鏈結性
唯一定義規則(one defination rule,簡稱odr)規定每個變數只能有乙個定義。而每個需要使用外部變數(有外部鏈結性)的檔案都必須宣告該變數。為了滿足這些需要,c++有兩種變數宣告:
定義宣告(defining declaration,簡稱定義definition)為變數分配記憶體。
引用宣告(referencing declaration,簡稱宣告declaration)不分配記憶體,參考已經存在的變數。使用說明符(specifier)關鍵字extern
,不提供初始化。
int a;
// defination, zero-initialization
extern
int b;
// declaration, defined elsewhere
extern
int c =3;
// defination due to constant-expression initialization
具有外部鏈結性的(靜態)變數稱為外部變數,除了定義該變數的檔案外,其他使用該變數的檔案需要使用關鍵字extern
(引用)宣告該變數。
使用說明符關鍵字static
字首的外部變數稱為靜態外部變數,如果與另乙個檔案中定義的外部變數重名,則靜態外部變數起作用/可見(in scope),僅在乙個檔案中的函式之間共享資料。
自動變數預設無鏈結性,定義時加上static
字首後,變成靜態區域性變數,具有靜態生存期。即使所在**塊不活躍,靜態區域性變數也存在,而且只在**塊中可見。所以,靜態區域性變數可以在函式呼叫之間儲存數值。雖然乙個函式可以被呼叫多次,但是函式裡的靜態區域性變數只在程式開始執行時初始化一次。
**示例1
// main.cpp
#include
#include
// atan() arc tangent
#include
"coordin.h"
// structure templates and function prototypes
using
namespace std;
// static variable
double pi =
4.0*
atan
(1.0);
// dynamic initialization
int num =0;
// count number of invoking rect2polar()
intmain
(int argc,
char
const
*ar**)
cout <<
"bye!\n"
;show_pi()
; cout <<
"global &pi = "
<<
&pi <<
'\n'
;return0;
}
// header file: coordin.h
#ifndef coordin_h_
#define coordin_h_
// structure declaration
struct polar
;struct rect
;// function prototye
struct polar rect2polar
(struct rect xypos)
;void
show_polar
(struct polar dapos)
;void
show_pi
(void);
// test scope-resolution operator
#endif
// implementation file: coordin.cpp
#include
#include
// sqrt() and atan2()
#include
"coordin.h"
// structure templates and function prototypes
using
namespace std;
// static variable, referencing declaration
// global variable, external linkage
extern
int num;
// static global variable, internal linkage, no conflict with main() pi
static
double pi =
4.0*
atan
(1.0);
// const double pi = 4.0 * atan(1.0);
// alse static global variable and internal linkage
struct polar rect2polar
(struct rect xypos)
void
show_polar
(struct polar dapos)
double rad2deg =
180.0
/ pi;
// initialize every invocation
cout <<
"distance = "
<< dapos.distance;
cout <<
", angle = "
<< dapos.angle * rad2deg;
cout <<
" degrees\n"
; cout <<
"num = "
<< num <<
", total distance = "
<< dist_sum <<
'\n'
; rad2deg++
;// no accumulation effect
}void
show_pi
(void
)
輸出
user@laptop separatecompilation % clang++ -std=c++11 -wall main.cpp coordin.cpp
user@laptop separatecompilation % ./a.out
enter x and y values: 3 4
static local variable address &dist_sum = 0x1015360e8
distance = 5, angle = 53.1301 degrees
num = 1, total distance = 5
next two numbers (q to quit): 8 6
distance = 10, angle = 36.8699 degrees
num = 2, total distance = 15
next two numbers (q to quit): q
bye!
local &pi = 0x7ffeee6d19e8
static global &::pi = 0x1015360f0
global &pi = 0x1015360d8
從列印出的位址可以看出,main.cpp
中全域性變數pi
、coordin.cpp
中的靜態全域性變數pi
和靜態區域性變數dist_num
的記憶體位址相近,與coordin.cpp
中的區域性變數pi
的位址相差甚遠。前者(統稱靜態變數)儲存在一固定記憶體塊中,後者儲存在另一記憶體塊(稱為棧stack)中。
c++的關鍵字中有兩種特定的修飾符,在變數宣告時提供關於儲存的資訊:
cv-限定符(cv-qualifier)
改編自c++ primer plus 6th edition by stephen prata ↩︎
C 靜態變數
在c 程式中,沒有全域性變數的概念,這意味著所有的成員變數只有該類的實 例才能操作這些資料,這起到了 資訊隱藏 的作用。但有些時候,這樣做卻不是個明智的選擇。假設我們要定義乙個圖書類,要求該類能儲存圖書的數量,即每增加一本圖書 定義乙個例項 圖書的數量應該加1。如果沒有靜態變數,我們需要將圖書的數量...
C 靜態變數
在c 程式中,沒有全域性變數的概念,這意味著所有的成員變數只有該類的例項才能操作這些資料,這起到了 資訊隱藏 的作用。但有些時候,這樣做卻不是個明智的選擇。假設我們要定義乙個圖書類,要求該類能儲存圖書的數量,即每增加一本圖書 定義乙個例項 圖書的數量應該加1。如果沒有靜態變數,我們需要將圖書的數量儲...
C 靜態變數
靜態變數 型別說明符是static。靜態變數屬於靜態儲存方式,其儲存空間為記憶體中的靜態資料區 在靜態儲存區內分配儲存單元 該區域中的資料在整個程式的執行期間一直占用這些儲存空間 在程式整個執行期間都不釋放 也可以認為是其記憶體位址不變,直到整個程式執行結束 相反,而auto自動變數,即動態區域性變...