C 靜態變數及其鏈結性

2021-10-19 13:32:05 字數 4206 閱讀 1252

承接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中全域性變數picoordin.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自動變數,即動態區域性變...