wake-up-neo.com

Anfangswert des Int-Arrays in C

Wenn Sie ein Array in C wie folgt deklarieren:

int array[10];

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

43
buzali

Wenn das Array in einer Funktion deklariert ist, ist der Wert undefiniert. int x[10]; in einer Funktion bedeutet: Übernehmen Sie den Besitz eines Speicherbereichs mit einer Größe von 10 int, ohne eine Initialisierung durchzuführen. Wenn das Array in einer Funktion als global eins oder als static deklariert ist, werden alle Elemente auf Null initialisiert, sofern sie nicht bereits initialisiert wurden.

61
AraK

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 wird jedoch empfohlen, Funktionsvariablen 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 setzen - ausgelassene Elemente werden automatisch auf 0 gesetzt:

int b[10] = {0};
20
qrdl

Warum werden Funktionslokale (auto - Speicherklasse) nicht initialisiert, wenn alles andere der Fall ist?

C ist in der Nähe der Hardware; das ist seine größte Stärke und seine größte Gefahr. Der Grund, warum auto Speicherklassenobjekte zufällige Anfangswerte haben, liegt darin, dass sie auf dem Stapel zugeordnet sind und die Entscheidung getroffen wurde, diese nicht automatisch zu löschen (teilweise, weil sie bei jedem Funktionsaufruf gelöscht werden müssten).

Andererseits müssen die Nicht-Objekte auto nur einmal gelöscht werden. Außerdem muss das Betriebssystem aus Sicherheitsgründen ohnehin zugewiesene Seiten löschen. Die Entwurfsentscheidung bestand hier also darin, eine Nullinitialisierung anzugeben. Warum ist Sicherheit auch beim Stack kein Problem? Eigentlich ist es zunächst geklärt. Der Junk, den Sie sehen, stammt aus 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 HLLs wie Basic und ganze OS-Kernel buchstäblich als riesige Assembler-Programme implementiert. (Mit bestimmten Ausnahmen an Orten wie IBM.)

12
DigitalRoss

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. In MSVC werden bei Debugbuilds automatische Variablen mit 0xcc initialisiert, während bei Nicht-Debugbuilds diese Variablen überhaupt nicht initialisiert werden.

7
MSN

Eine C-Variablendeklaration weist den Compiler lediglich an, einen Speicherbereich für Sie zu reservieren und zu benennen. Bei automatischen Variablen, auch Stapelvariablen genannt, werden die Werte in diesem Speicher nicht von den vorherigen Werten geändert. Globale und statische Variablen werden beim Programmstart auf Null gesetzt.

Einige Compiler im nicht optimierten Debug-Modus setzen automatische Variablen auf Null. In 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 aufzufordern, 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 versehen, die es haben sollte. Das ist effizienter und vermeidet das zweimalige Schreiben in das Array.

5
Zan Lynx

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

Abgesehen von den obigen lokalen Array-/Strukturdaten behalten statische (global/lokal) und globale Space-Member 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

4
mav_2k

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

ZUSAMMENFASSUNG:

Arrays werden initialisiert. Wenn Sie ein reguläres Array mit lokalem Gültigkeitsbereich deklarieren (z. B. innerhalb einer Funktion), werden seine Elemente standardmäßig nicht mit einem Wert initialisiert, sodass ihr Inhalt unbestimmt bleibt, bis wir einen bestimmten Wert in ihnen speichern. Die Elemente von globalen und statischen Arrays werden dagegen automatisch mit ihren Standardwerten initialisiert, was bedeutet, dass sie für alle grundlegenden Typen mit Nullen gefüllt sind.

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 geschweifte Klammern {} setzen. Beispielsweise:

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

Die relevanten Abschnitte aus der C-Norm (Schwerpunkt Mine):

5.1.2 Ausführungsumgebungen

Alle Objekte mit statische Speicherung Dauer sollen initialisiert werden (auf ihre Anfangswerte gesetzt) ​​vor dem Programmstart.

6.2.4 Aufbewahrungsdauer von Objekten

Ein Objekt, dessen Bezeichner mit externer oder interner Verknüpfung oder mit dem Speicherklassenspezifizierer static deklariert ist, hat die Dauer statischer Speicher.

6.2.5 Typen

Array und Strukturtypen werden gemeinsam Aggregat -Typen genannt.

6.7.8 Initialisierung

Wenn ein Objekt mit automatische Speicherung Dauer nicht explizit initialisiert ist , ist Wert ist unbestimmt . Wenn ein Objekt mit statischer Speicher Dauer nicht explizit initialisiert ist , dann :

  • wenn es einen Zeigertyp hat, wird es mit einem Nullzeiger initialisiert.
  • wenn es einen arithmetischen Typ hat, wird es mit (positiv oder vorzeichenlos) Null initialisiert.
  • wenn es sich um ein Aggregat handelt, wird jedes Mitglied nach diesen Regeln (rekursiv) initialisiert.
  • wenn es sich um eine Gewerkschaft handelt, wird das zuerst genannte Mitglied nach diesen Regeln (rekursiv) initialisiert.
1
sergej