Anfangswert des int-Arrays in C

Lesezeit: 7 Minuten

Wenn Sie ein Array in C wie folgt deklarieren:

int array[10];

Was ist der Anfangswert der ganzen Zahlen? Ich erhalte unterschiedliche Ergebnisse mit verschiedenen Compilern und möchte wissen, ob es etwas mit dem Compiler oder dem Betriebssystem zu tun hat.

Benutzeravatar von Khaled Alshaya
Khaled Alshaya

Wenn das Array in einer Funktion deklariert ist, ist der Wert undefiniert. int x[10]; in einer Funktion bedeutet: den Besitz eines 10-int-großen Speicherbereichs übernehmen, ohne eine Initialisierung durchzuführen. Wenn das Array als global oder als deklariert ist static in einer Funktion werden alle Elemente auf Null initialisiert, wenn sie nicht bereits initialisiert sind.

  • Korrekt. Wenn es nicht global ist, enthält es den zufälligen Müll, der sich zuvor in diesem Speicherklumpen befand. Hat nichts mit dem Compiler zu tun. Wenn Sie etwas Bestimmtes darin haben wollen, legen Sie es dort hin.

    – JasonWoof

    12. September 2009 um 3:52 Uhr

  • @buzali Einige Compiler/Toolchains setzen Variablen und zugewiesenen Speicher immer auf Null, meistens, wenn Sie im “Debug” -Modus bauen (keine Optimierungen aktiviert). Dies dient normalerweise dazu, eine deterministische Debugging-Umgebung zu erstellen, wenn Sie beim Prototyping von Code vergessen, eine Variable zu initialisieren. Die andere Möglichkeit ist, dass der Speicher, den das Array verwendet, zufällig Nullen enthält.

    – Drakonit

    12. September 2009 um 4:16 Uhr

  • Falsch. Der Gültigkeitsbereich der Variablen spielt keine Rolle – die Speicherklasse schon.

    – qrdl

    12. September 2009 um 6:07 Uhr

  • @buzali: nein, das willst du nicht. Wenn Sie das Array mit Nullen initialisieren möchten, schreiben Sie int array[10] = {0};. Den Compiler dazu zu bringen, dies automatisch zu tun, bedeutet lediglich, dass Sie Code schreiben, der nur im Debug-Modus funktioniert und beim Freigeben abbricht oder von jemand anderem mit anderen Optionen kompiliert wird.

    – Steve Jessop

    12. September 2009 um 13:08 Uhr

  • @AraK: Es kann sich auch lohnen, Ihrer Antwort hinzuzufügen, dass a static Die innerhalb einer Funktion definierte Variable wird ebenfalls mit Nullen initialisiert.

    – Steve Melnikoff

    12. September 2009 um 16:04 Uhr

Standardmäßig werden alle globalen und funktionsstatischen Variablen automatisch auf 0 initialisiert. Automatische Variablen werden nicht initialisiert.

int a[10];  // global - all elements are initialised to 0

void foo(void) {
    int b[10];    // automatic storage - contain junk
    static int c[10]; // static - initialised to 0
}

Es empfiehlt sich jedoch, die Funktionsvariable unabhängig von ihrer Speicherklasse immer manuell zu initialisieren. Um alle Array-Elemente auf 0 zu setzen, müssen Sie nur das erste Array-Element auf 0 zuweisen – ausgelassene Elemente werden automatisch auf 0 gesetzt:

int b[10] = {0};

  • Um pedantisch zu sein, Dateibereichsvariablen (Globals) haben eine statische Speicherklasse, weshalb sie auf 0 initialisiert werden.

    – Johannes Bode

    12. September 2009 um 14:23 Uhr

  • @John Ja, aber weil statisch auf Dateiebene eine andere Bedeutung hat, habe ich es einfach “global” genannt, sei es dateiglobal oder programmglobal

    – qrdl

    12. September 2009 um 15:34 Uhr

  • Ich verstehe nicht, warum es sinnvoll ist, Zyklen beim Initialisieren eines großen Puffers zu verschwenden, den Sie in der nächsten Zeile mit Daten aus einer Datei/einem Netzwerk laden werden.

    – Martin Jakob

    28. Juli 2014 um 19:33 Uhr

Benutzeravatar von DigitalRoss
DigitalRoss

Warum sind Funktionslokale (auto Speicherklasse) nicht initialisiert, wenn alles andere ist?

C ist nahe an der Hardware; das ist seine größte Stärke und seine größte Gefahr. Der Grund auto Speicherklassenobjekte haben zufällige Anfangswerte, weil sie auf dem Stapel zugewiesen werden und eine Entwurfsentscheidung getroffen wurde, diese nicht automatisch zu löschen (teilweise, weil sie bei jedem Funktionsaufruf gelöscht werden müssten).

Andererseits sind die Nicht-auto Objekte müssen nur einmal geräumt werden. Außerdem muss das Betriebssystem zugewiesene Seiten aus Sicherheitsgründen ohnehin löschen. Die Entwurfsentscheidung bestand hier also darin, die Nullinitialisierung anzugeben. Warum ist die Sicherheit beim Stack nicht auch ein Thema? Eigentlich ist es erstmal geräumt. Der Müll, den Sie sehen, stammt von früheren Instanzen der Aufrufrahmen Ihres eigenen Programms und dem von ihnen aufgerufenen Bibliothekscode.

Das Endergebnis ist schneller, speichereffizienter Code. Alle Vorteile der Montage ohne Schmerzen. Bevor dmr C erfand, wurden “HLL”s wie Basic und ganze OS-Kernel wirklich, buchstäblich, als riesige Assembler-Programme implementiert. (Mit bestimmten Ausnahmen an Orten wie IBM.)

  • Das ist meine Lieblingsantwort. Dies ist eine sehr gute, klare und prägnante Beschreibung, warum unterschiedliche Designentscheidungen für unterschiedliche Speicherklassen getroffen werden.

    – Po-wei Huang

    21. Mai um 12:59 Uhr

Gemäß der C-Norm, 6.7.8 (Anmerkung 10):

Wenn ein Objekt mit automatischer Speicherdauer nicht explizit initialisiert wird, ist sein Wert unbestimmt.

Es kommt also auf den Compiler an. Mit MSVC initialisieren Debug-Builds automatische Variablen mit 0xcc, während Nicht-Debug-Builds diese Variablen überhaupt nicht initialisieren.

Benutzeravatar von Zan Lynx
Zan Luchs

Die AC-Variablendeklaration weist den Compiler lediglich an, einen Speicherbereich für Sie zu reservieren und zu benennen. Bei automatischen Variablen, auch Stack-Variablen genannt, werden die Werte in diesem Speicher gegenüber dem vorherigen nicht geändert. Globale und statische Variablen werden beim Programmstart auf Null gesetzt.

Einige Compiler im nicht optimierten Debug-Modus setzen automatische Variablen auf Null. Bei neueren Compilern ist es jedoch üblich geworden, die Werte auf einen bekannten schlechten Wert zu setzen, damit der Programmierer nicht unwissentlich Code schreibt, der davon abhängt, dass eine Null gesetzt wird.

Um den Compiler zu bitten, ein Array für Sie auf Null zu setzen, können Sie es wie folgt schreiben:

int array[10] = {0};

Noch besser ist es, das Array mit den Werten zu setzen, die es haben sollte. Das ist effizienter und vermeidet das doppelte Schreiben in das Array.

  • Wissen Sie, wie Sie dem Compiler sagen können, dass er die Werte auf Null setzen soll?? Ich verwende GCC … gibt es einen Debug-Parameter, der dies tut?

    – Busali

    12. September 2009 um 4:24 Uhr

  • Verlassen Sie sich nicht auf den Compiler, um das Array zu initialisieren, verwenden Sie einen expliziten Initialisierer, wie Zan vorschlägt. Selbst wenn der aktuelle gcc Arrays in einem Debug-Modus auf Null setzt, kann der nächste entscheiden, sie mit einem völlig anderen Wert zu füllen, was Sie in 5 Jahren mit einem sehr schwer zu lokalisierenden Fehler zurücklässt. Geben Sie einfach die zusätzlichen 5 Zeichen ein und verwenden Sie das int-Array[10] = {0};

    – Sonnenfinsternis

    12. September 2009 um 4:43 Uhr

  • Offensichtlich falsch. Variablen aus dem Datensegment werden immer genullt.

    – qrdl

    12. September 2009 um 6:10 Uhr

  • weit nicht immer genullt

    – Benutzer3063349

    12. September 2017 um 13:46 Uhr

In den meisten neuesten Compilern (z. B. gcc/vc++) werden teilweise initialisierte lokale Array-/Strukturmitglieder standardmäßig auf null (int), NULL (char/char-String), 0,000000 (float/double) initialisiert.

Abgesehen von lokalen Array-/Strukturdaten wie oben behalten auch statische (global/lokal) und globale Raummitglieder dieselbe Eigenschaft bei.

int a[5] = {0,1,2};
printf("%d %d %d\n",*a, *(a+2), *(a+4));

struct s1
{
int i1;
int i2;
int i3;
char c;
char str[5];
};

struct s1 s11 = {1};
    printf("%d %d %d %c %s\n",s11.i1,s11.i2, s11.i3, s11.c, s11.str);
    if(!s11.c)
        printf("s11.c is null\n");
    if(!*(s11.str))
        printf("s11.str is null\n");

In gcc/vc++ sollte die Ausgabe sein:

0 2 0 1 0 0 0,000000 s11.c ist null s11.str ist null

  • Wissen Sie, wie Sie dem Compiler sagen können, dass er die Werte auf Null setzen soll?? Ich verwende GCC … gibt es einen Debug-Parameter, der dies tut?

    – Busali

    12. September 2009 um 4:24 Uhr

  • Verlassen Sie sich nicht auf den Compiler, um das Array zu initialisieren, verwenden Sie einen expliziten Initialisierer, wie Zan vorschlägt. Selbst wenn der aktuelle gcc Arrays in einem Debug-Modus auf Null setzt, kann der nächste entscheiden, sie mit einem völlig anderen Wert zu füllen, was Sie in 5 Jahren mit einem sehr schwer zu lokalisierenden Fehler zurücklässt. Geben Sie einfach die zusätzlichen 5 Zeichen ein und verwenden Sie das int-Array[10] = {0};

    – Sonnenfinsternis

    12. September 2009 um 4:43 Uhr

  • Offensichtlich falsch. Variablen aus dem Datensegment werden immer genullt.

    – qrdl

    12. September 2009 um 6:10 Uhr

  • weit nicht immer genullt

    – Benutzer3063349

    12. September 2017 um 13:46 Uhr

Benutzeravatar von KV Prajapati
KV Prajapati

Texte von http://www.cplusplus.com/doc/tutorial/arrays/

ZUSAMMENFASSUNG:

Arrays initialisieren. Wenn wir ein reguläres Array mit lokalem Geltungsbereich (z. B. innerhalb einer Funktion) deklarieren und nichts anderes angeben, werden seine Elemente standardmäßig mit keinem Wert initialisiert, sodass ihr Inhalt unbestimmt ist, bis wir einen Wert in ihnen speichern. Die Elemente globaler und statischer Arrays werden dagegen automatisch mit ihren Defaultwerten initialisiert, was für alle fundamentalen Typen bedeutet, dass sie mit Nullen aufgefüllt werden.

In beiden Fällen, lokal und global, haben wir bei der Deklaration eines Arrays die Möglichkeit, jedem seiner Elemente Anfangswerte zuzuweisen, indem wir die Werte in geschweiften Klammern { } einschließen. Zum Beispiel:

int billy [5] = { 16, 2, 77, 40, 12071 };

1414680cookie-checkAnfangswert des int-Arrays in C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy