2014-11-03 19 views
6

od 21 wieku C książce:Inicjowanie statyczna zmienna o wartości nonconstant

zmiennych statycznych, nawet wewnątrz funkcji, są inicjowane po uruchomieniu programu, przed głównym, więc nie można zainicjować im o wartości nietrwałej.

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

Jest to kłopot, ale łatwo rozwiązać za pomocą makra, aby rozpocząć od zera i przeznaczyć na pierwszym użyciu:

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

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

Nie rozumiem co za różnica makro wykonane. Czy nie robi dokładnie to samo po wstępnym przetwarzaniu?


+0

Niezbyt bezpieczne zalecenie tej książki, ale szybkie i brudne niebezpieczne Hack. – alk

Odpowiedz

6

Czy to nie robi dokładnie to samo po wstępnym przetwarzaniu?

Nie, oba niekoniecznie zachowują się tak samo.

to initalisation jest zagwarantowane do prowadzony tylko raz:

static int i = 42; /* Initialisation */ 

Przypisanie

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

nie jest, jak każdym razem przepływu programu osiąga linii X i i jest równy 0, a następnie ijest ustawiony na na 42 (ponownie).

Przykłady:

#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; 
} 

uruchomić go i zobaczyć różnicę:

42 
43 
0 

42 
43 
42 
+1

Po prostu wyjaśnienie, "static int i = 0" nadal działa tylko raz w drugim przykładzie. Następnie "if (! I)" zawsze będzie prawdziwe w tym przykładzie, więc 'i = 42' będzie zawsze wywoływane. – Jite

+0

@Jite: Dodałem przykład. – alk

+0

Masz rację. Zły odczytałem pytanie. – Jite

3

Preprocessor zastępuje tylko tekst, tak aby końcowy wynik Staticdef makro jest:

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

można wpisać, że sam, jeśli chcesz lub użyj makra.

Jest to oczywiście inna niż nieprawidłowej wersji:

static gsl_vector *scratch = gsl_vector_alloc(20); 

Nie zalecamy używanie makra, gdyż nie mogą być zapakowane w do {} while, a jedynie zaciemnia kod.

Powiązane problemy