2014-11-03 74 views
6

從21世紀城市本書靜態變量:在程序啓動時,前主,所以你不能初始化它們 初始化有非常數值

靜態變量,即使是那些在函數中,初始化 具有非恆定價值。

//this fails: can't call gsl_vector_alloc() before main() starts 
static gsl_vector *scratch = gsl_vector_alloc(20); 

這是一種煩惱,但與宏迎刃而解開始在零 和分配上首次使用:

#define Staticdef(type, var, initialization) \ 
static type var = 0; \ 
if (!(var)) var = (initialization); 

//usage: 
Staticdef(gsl_vector*, scratch, gsl_vector_alloc(20)); 

我不明白,對宏進行什麼區別。預處理後它不完全一樣嗎?


+0

不通過這本書非常安全的建議,但更多的是快速和骯髒的劈不安全。 – alk 2014-11-03 15:57:32

回答

6

預處理之後它不完全一樣嗎?

不,兩者不一定表現相同。

這initalisation是保證運行一次

static int i = 42; /* Initialisation */ 

這種分配

static int i = 0; 
if (!i) /* line X */ 
    i = 42; /* Assignment */ 

並非如每次程序流到達線X和i等於0然後i設置爲42(再次)。

例子:

#include <stdio.h> 

void foo(int inew) 
{ 
    static int i = 42; 

    printf("%d\n", i); 

    i = inew; 
} 

void bar(int inew) 
{ 
    static int i = 0; 
    if (!i) 
    i = 42; 

    printf("%d\n", i); 

    i = inew; 
} 

int main(void) 
{ 
    foo(43); 
    foo(0); 
    foo(44); 

    printf("\n"); 

    bar(43); 
    bar(0); 
    bar(44); 

    return 0; 
} 

運行它,看到了差距:

42 
43 
0 

42 
43 
42 
+1

只是澄清一下,'static int i = 0'仍然只在第二個例子中運行一次。之後'if(!i)'在這個例子中總是成立,所以總是會調用'i = 42'。 – Jite 2014-11-03 16:17:57

+0

@Jite:我添加了一個例子。 – alk 2014-11-03 16:27:32

+0

你說得對。我誤解了這個問題。 – Jite 2014-11-03 16:58:06

3

預處理只是取代了文字,從而使Staticdef宏的最終結果是:

static gsl_vector *scratch = 0 ; 
if (!(scratch)) scratch = (gsl_vector_alloc(20)); 

您可以鍵入自己,如果你願意,或者使用宏。

這當然比不正確的版本不同:

static gsl_vector *scratch = gsl_vector_alloc(20); 

我建議不要使用宏,因爲它不能在DO {}而被包裹,只混淆了代碼。