Mit der folgenden Erklärung
int array[ROW][COLUMN]={0};
Ich bekomme das Array mit allen Nullen, aber mit der folgenden
int array[ROW][COLUMN]={1};
Ich bekomme das Array nicht mit allen einem Wert. Der Standardwert ist immer noch 0.
Warum dieses Verhalten und wie kann ich mit allen 1 initialisieren?
EDIT: Ich habe gerade verstanden, dass bei Verwendung memset
mit dem Wert 1 jedes Byte auf 1 gesetzt wird und daher der tatsächliche Wert jeder Array-Zelle nicht 1 ist, sondern 16843009
. Wie setze ich es auf 1?
c
arrays
initialization
Krake
quelle
quelle
why and how
beides. :)Antworten:
Sie erhalten dieses Verhalten, weil
int array [ROW][COLUMN] = {1};
dies nicht bedeutet, dass "alle Elemente auf eins gesetzt werden". Lassen Sie mich versuchen, Schritt für Schritt zu erklären, wie dies funktioniert.Die explizite, zu klare Methode zum Initialisieren Ihres Arrays lautet wie folgt:
#define ROW 2 #define COLUMN 2 int array [ROW][COLUMN] = { {0, 0}, {0, 0} };
Mit C können Sie jedoch einige Elemente in einem Array (oder einer Struktur / Vereinigung) weglassen. Sie könnten zum Beispiel schreiben:
int array [ROW][COLUMN] = { {1, 2} };
Das heißt, initialisieren Sie die ersten Elemente mit 1 und 2 und den Rest der Elemente "als ob sie eine statische Speicherdauer hätten". In C gibt es eine Regel, die besagt, dass alle Objekte mit statischer Speicherdauer, die vom Programmierer nicht explizit initialisiert werden, auf Null gesetzt werden müssen.
Im obigen Beispiel wird die erste Zeile auf 1,2 und die nächste auf 0,0 gesetzt, da wir ihnen keine expliziten Werte gegeben haben.
Als nächstes gibt es in C eine Regel, die einen lockeren Klammerstil zulässt. Das erste Beispiel könnte genauso gut geschrieben werden wie
int array [ROW][COLUMN] = {0, 0, 0, 0};
Obwohl dies natürlich ein schlechter Stil ist, ist es schwieriger zu lesen und zu verstehen. Diese Regel ist jedoch praktisch, da wir damit schreiben können
int array [ROW][COLUMN] = {0};
Dies bedeutet: "Initialisieren Sie die allererste Spalte in der ersten Zeile auf 0 und alle anderen Elemente so, als ob sie eine statische Speicherdauer hätten, dh setzen Sie sie auf Null."
Deshalb, wenn Sie es versuchen
int array [ROW][COLUMN] = {1};
es bedeutet "initialisiere die allererste Spalte in der ersten Zeile auf 1 und setze alle anderen Elemente auf Null".
quelle
int array [ROW][COLUMN] = {{0}};
Wenn Sie das Array initialisieren möchten,
-1
können Sie Folgendes verwenden:memset(array, -1, sizeof(array[0][0]) * row * count)
Aber das wird funktionieren
0
und-1
nurquelle
0000
und1111
<cstring>
in c ++int array[ROW][COLUMN]={1};
Dies initialisiert nur das erste Element auf 1. Alles andere erhält eine 0.
In der ersten Instanz machen Sie dasselbe: Sie initialisieren das erste Element auf 0 und der Rest auf 0.
Der Grund ist einfach: Für ein Array initialisiert der Compiler jeden Wert, den Sie nicht mit 0 angeben.
Mit einem
char
Array können Siememset
jedes Byte festlegen, dies funktioniert jedoch im Allgemeinen nicht mit einemint
Array (obwohl es für 0 in Ordnung ist).Eine allgemeine
for
Schleife erledigt dies schnell:for (int i = 0; i < ROW; i++) for (int j = 0; j < COLUMN; j++) array[i][j] = 1;
Oder möglicherweise schneller (je nach Compiler)
for (int i = 0; i < ROW*COLUMN; i++) *((int*)a + i) = 1;
quelle
0
initialisiert auch nur den ersten Wert. Der Rest0
wird dann standardmäßig mit initialisiert .value
Feld inmemset
1 ist, dann ist der tatsächliche Wert in der Matrix nicht 1, aber2^0 + 2^8 + 2^16 + 2^24
?memset
Setzt jedes Byte in seinem Ziel auf den angegebenen Wert. Dies funktioniert nicht, um einen Wertint
auf 1 zu setzen . Esmemset
kann nicht zum Festlegen von Werten für Mehrbyte-Objekte verwendet werden, es sei denn, Sie möchten, dass jedes Byte des Objekts auf denselben Wert gesetzt wird.Beachten Sie, dass GCC eine Erweiterung der angegebenen Initialisierungsnotation hat, die für den Kontext sehr nützlich ist. Es ist auch
clang
kommentarlos erlaubt (teilweise weil es versucht, mit GCC kompatibel zu sein).Mit der Erweiterungsnotation können Sie
...
einen Bereich von Elementen festlegen, die mit dem folgenden Wert initialisiert werden sollen. Zum Beispiel:#include <stdio.h> enum { ROW = 5, COLUMN = 10 }; int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = 1 } }; int main(void) { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COLUMN; j++) printf("%2d", array[i][j]); putchar('\n'); } return 0; }
Die Ausgabe ist nicht überraschend:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Beachten Sie, dass Fortran 66 (Fortran IV) Wiederholungszählungen für Initialisierer für Arrays hatte; Es kam mir immer seltsam vor, dass C sie nicht bekam, als der Sprache bestimmte Initialisierer hinzugefügt wurden. Und Pascal verwendet die
0..9
Notation, um den Bereich von 0 bis einschließlich 9 zu bestimmen, aber C wird nicht..
als Token verwendet, so dass es nicht verwunderlich ist, dass dies nicht verwendet wurde.Beachten Sie, dass die Leerzeichen um die
...
Notation im Wesentlichen obligatorisch sind. Wenn sie an Zahlen angehängt sind, wird die Zahl als Gleitkommazahl interpretiert. Zum Beispiel0...9
würde , wie in Token aufgeteilt werden0.
,.
,.9
und Gleitkommazahlen dürfen nicht als Array - Indizes. Mit den genannten Konstanten...ROW-1
würde das keine Probleme verursachen, aber es ist besser, sich in die sicheren Gewohnheiten zu begeben.Nachträge:
Ich stelle nebenbei fest, dass GCC 7.3.0 Folgendes ablehnt:
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = { 1 } } };
Hier gibt es einen zusätzlichen Satz geschweifter Klammern um den skalaren Initialisierer
1
(error: braces around scalar initializer [-Werror]
). Ich bin mir nicht sicher, ob dies korrekt ist, da Sie normalerweise geschweifte Klammern um einen Skalar in angeben könnenint a = { 1 };
, was vom Standard ausdrücklich zugelassen wird. Ich bin mir auch nicht sicher, ob es falsch ist.Ich frage mich auch, ob eine bessere Notation wäre
[0]...[9]
- das ist eindeutig, kann nicht mit einer anderen gültigen Syntax verwechselt werden und vermeidet Verwechslungen mit Gleitkommazahlen.int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };
Vielleicht würde das Normungsgremium das in Betracht ziehen?
quelle
Verwenden Sie die folgende Methode, um ein 2d-Array mit Null zu initialisieren:
int arr[n][m] = {};
HINWEIS : Die obige Methode funktioniert nur zum Initialisieren mit 0;
quelle
Verwenden Vektor Array statt:
vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));
quelle
char grid[row][col]; memset(grid, ' ', sizeof(grid));
Dies dient zum Initialisieren von Char-Array-Elementen in Leerzeichen.
quelle