Suche…


Initialisierung von Variablen in C

Ohne explizite Initialisierung werden externe und static Variablen garantiert auf Null initialisiert. automatische Variablen (einschließlich der register haben unbestimmte 1 (dh garbage) Anfangswerte.

Skalare Variablen können initialisiert werden, wenn sie definiert werden, indem dem Namen ein Gleichheitszeichen und ein Ausdruck folgen:

int x = 1;
char squota = '\'';
long day = 1000L * 60L * 60L * 24L; /* milliseconds/day */

Bei externen und static Variablen muss der Initialisierer ein konstanter Ausdruck 2 sein . Die Initialisierung erfolgt einmalig, konzeptionell, bevor das Programm ausgeführt wird.

Bei automatischen und register ist der Initialisierer nicht darauf beschränkt, eine Konstante zu sein: Es kann sich um einen beliebigen Ausdruck handeln, der zuvor definierte Werte enthält, sogar Funktionsaufrufe.

Sehen Sie sich zum Beispiel den Code-Ausschnitt unten an

int binsearch(int x, int v[], int n)
{
   int low = 0;
   int high = n - 1;
   int mid;
   ...
}

anstatt

   int low, high, mid;

   low = 0;
   high = n - 1;

Die Initialisierung automatischer Variablen ist eigentlich nur eine Abkürzung für Zuweisungsanweisungen. Welche Form zu bevorzugen, ist weitgehend Geschmacksache. Im Allgemeinen verwenden wir explizite Zuweisungen, da Initialisierer in Deklarationen schwieriger zu erkennen sind und weiter von der Verwendungsstelle entfernt sind. Auf der anderen Seite sollten Variablen nur dann deklariert werden, wenn sie verwendet werden, wann immer dies möglich ist.

Array initialisieren:

Ein Array kann initialisiert werden, indem es seiner Deklaration mit einer Liste von Initialisierern folgt, die in geschweifte Klammern eingeschlossen und durch Kommas getrennt sind.

Um beispielsweise ein Array-Tag mit der Anzahl der Tage in jedem Monat zu initialisieren:

int days_of_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }

(Beachten Sie, dass der Januar in dieser Struktur als Monat Null codiert ist.)

Wenn die Größe des Arrays weggelassen wird, berechnet der Compiler die Länge, indem er die Initialisierer zählt, von denen in diesem Fall 12 vorhanden sind.

Wenn für ein Array weniger Initialisierer als die angegebene Größe vorhanden sind, sind die anderen für alle Variablentypen gleich Null.

Es ist ein Fehler, zu viele Initialisierer zu haben. Es gibt keine Standardmethode, um die Wiederholung eines Initialisierers anzugeben. GCC hat jedoch eine Erweiterung, um dies zu tun.

C99

In C89 / C90 oder früheren Versionen von C gab es keine Möglichkeit, ein Element in der Mitte eines Arrays zu initialisieren, ohne alle vorherigen Werte anzugeben.

C99

Mit C99 und darüber, bezeichnet initializers können Sie beliebige Elemente eines Arrays initialisieren, alle nicht initialisierte Werte als Nullen zu verlassen.

Character Arrays initialisieren:

Character Arrays sind ein Spezialfall der Initialisierung. Anstelle der geschriebenen Klammern und Kommas kann eine Zeichenfolge verwendet werden:

char chr_array[] = "hello";

ist eine Abkürzung für die längere aber gleichwertige:

char chr_array[] = { 'h', 'e', 'l', 'l', 'o', '\0' };

In diesem Fall beträgt die Array-Größe sechs (fünf Zeichen plus das abschließende '\0' ).

1 Was passiert mit einer deklarierten, nicht initialisierten Variablen in C? Hat es einen Wert?

2 Beachten Sie, dass ein konstanter Ausdruck als etwas definiert wird, das zur Kompilierzeit ausgewertet werden kann. int global_var = f(); ist ungültig. Ein anderes weit verbreitetes Missverständnis ist, eine const qualifizierte Variable als konstanten Ausdruck zu betrachten . In C bedeutet const "Nur-Lesen", nicht "Kompilierzeitkonstante". Also globale Definitionen wie const int SIZE = 10; int global_arr[SIZE]; und const int SIZE = 10; int global_var = SIZE; sind nicht legal in C.

Initialisieren von Strukturen und Arrays von Strukturen

Strukturen und Arrays von Strukturen können durch eine Reihe von Werten, die in geschweifte Klammern eingeschlossen sind, initialisiert werden, ein Wert pro Element der Struktur.

struct Date
{
    int year;
    int month;
    int day;
};

struct Date us_independence_day = { 1776, 7, 4 };

struct Date uk_battles[] =
{
    { 1066, 10, 14 },    // Battle of Hastings
    { 1815,  6, 18 },    // Battle of Waterloo
    { 1805, 10, 21 },    // Battle of Trafalgar
};

Beachten Sie, dass die Array-Initialisierung ohne die inneren Klammern geschrieben werden könnte und in früheren Zeiten (vor 1990) häufig ohne sie geschrieben worden wäre:

struct Date uk_battles[] =
{
    1066, 10, 14,    // Battle of Hastings
    1815,  6, 18,    // Battle of Waterloo
    1805, 10, 21,    // Battle of Trafalgar
};

Obwohl dies funktioniert, ist es nicht gut im modernen Stil - Sie sollten nicht versuchen, diese Notation in neuem Code zu verwenden, und sollte die Compiler-Warnungen korrigieren, die normalerweise ausgegeben werden.

Siehe auch benannte Initialisierer .

Verwenden von festgelegten Initialisierern

C99

Mit C99 wurde das Konzept der vorgesehenen Initialisierer eingeführt. Damit können Sie festlegen, welche Elemente eines Arrays, einer Struktur oder einer Vereinigung durch die folgenden Werte initialisiert werden sollen.

Designierte Initialisierer für Array-Elemente

Für einen einfachen Typ wie plain int :

int array[] = { [4] = 29, [5] = 31, [17] = 101, [18] = 103, [19] = 107, [20] = 109 };

Der Begriff in eckigen Klammern, bei dem es sich um einen konstanten ganzzahligen Ausdruck handeln kann, gibt an, welches Element des Arrays durch den Wert des Begriffs nach dem = -Zeichen initialisiert werden soll. Nicht spezifizierte Elemente werden standardmäßig initialisiert, dh es werden Nullen definiert. Das Beispiel zeigt die angegebenen Initialisierer in Reihenfolge. Sie müssen nicht in Ordnung sein. Das Beispiel zeigt Lücken; das ist legitim. Das Beispiel zeigt nicht zwei verschiedene Initialisierungen für dasselbe Element. das ist auch erlaubt (ISO / IEC 9899: 2011, §6.7.9 Initialisierung, ¶19 Die Initialisierung erfolgt in der Reihenfolge der Initialisiererliste, wobei jeder Initialisierer, der für ein bestimmtes Unterobjekt vorgesehen ist, alle zuvor aufgelisteten Initialisierer für dasselbe Unterobjekt überschreibt ).

In diesem Beispiel ist die Größe des Arrays nicht explizit definiert. Daher gibt der in den angegebenen Initialisierern angegebene maximale Index die Größe des Arrays an - im Beispiel also 21 Elemente. Wenn die Größe definiert wurde, wäre das Initialisieren eines Eintrags über das Arrayende hinaus wie üblich ein Fehler.

Designierte Initialisierer für Strukturen

Mit dem können Sie angeben, welche Elemente einer Struktur initialisiert werden sollen . element :

struct Date
{
    int year;
    int month;
    int day;
};

struct Date us_independence_day = { .day = 4, .month = 7, .year = 1776 };

Wenn Elemente nicht aufgelistet sind, werden sie standardmäßig initialisiert (auf Null gesetzt).

Designierter Initialisierer für Gewerkschaften

Sie können angeben, welches Element einer Union mit einem bestimmten Initialisierer initialisiert werden soll.

C89

Vor dem C-Standard gab es keine Möglichkeit, eine union zu initialisieren. Mit dem Standard C89 / C90 können Sie das erste Mitglied einer union initialisieren. Die Auswahl des ersten Mitglieds ist daher wichtig.

struct discriminated_union
{
    enum { DU_INT, DU_DOUBLE } discriminant;
    union
    {
        int     du_int;
        double  du_double;
    } du;
};

struct discriminated_union du1 = { .discriminant = DU_INT, .du = { .du_int = 1 } };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du = { .du_double = 3.14159 } };
C11

Beachten Sie, dass Sie mit C11 anonyme Gewerkschaftsmitglieder innerhalb einer Struktur verwenden können, sodass Sie im vorherigen Beispiel keinen du Namen benötigen:

struct discriminated_union
{
    enum { DU_INT, DU_DOUBLE } discriminant;
    union
    {
        int     du_int;
        double  du_double;
    };
};

struct discriminated_union du1 = { .discriminant = DU_INT, .du_int = 1 };
struct discriminated_union du2 = { .discriminant = DU_DOUBLE, .du_double = 3.14159 };

Designierte Initialisierer für Arrays von Strukturen usw

Diese Konstrukte können für Arrays von Strukturen kombiniert werden, die Elemente enthalten, die Arrays usw. sind. Durch Verwendung vollständiger Sätze von geschweiften Klammern wird sichergestellt, dass die Notation eindeutig ist.

typedef struct Date Date;  // See earlier in this example

struct date_range
{
    Date    dr_from;
    Date    dr_to;
    char    dr_what[80];
};

struct date_range ranges[] =
{
    [3] = { .dr_from = { .year = 1066, .month = 10, .day = 14 },
            .dr_to   = { .year = 1066, .month = 12, .day = 25 },
            .dr_what = "Battle of Hastings to Coronation of William the Conqueror",
          },
    [2] = { .dr_from = { .month = 7, .day =  4, .year = 1776 },
            .dr_to   = { .month = 5, .day = 14, .year = 1787 },
            .dr_what = "US Declaration of Independence to Constitutional Convention",
          }
 };

Angeben von Bereichen in Array-Initialisierern

GCC bietet eine Erweiterung , mit der Sie einen Bereich von Elementen in einem Array angeben können, für den derselbe Initialisierer angegeben werden sollte:

int array[] = { [3 ... 7] = 29, 19 = 107 };

Die dreifachen Punkte müssen von den Zahlen getrennt sein, damit nicht einer der Punkte als Teil einer Gleitkommazahl interpretiert wird ( Maximale Munch- Regel).



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow