Wie kann ich mit C ++ mehrere Variablen in einer Zeile deklarieren und definieren?

172

Ich denke immer, wenn ich diese drei Variablen deklariere, haben sie alle den Wert 0

int column, row, index = 0;

Aber ich finde, dass nur der Index gleich Null ist und die anderen wie 844553 und 2423445 Junk sind.

Wie kann ich alle diese Variablen auf Null initialisieren, ohne jede Variable in einer neuen Zeile zu deklarieren?

Sam
quelle
36
Vorsicht bei diesen einzeiligen Deklarationen mit mehreren Variablen. Es ist einfacher als Sie denken, einen int-Zeiger gefolgt von einer Liste regulärer Ganzzahlen zu deklarieren ( int* a, b, c;macht nicht das, wie es aussieht).
Chris Eberle
4
Es gibt nur drei Variablen, Alter, schreibe =0für jede in ihren Definitionen. Und wenn Sie wirklich viele Variablen möchten, versuchen Sie es mit einem Array: int a[10]={0}Initialisiert jedes a[i]für Sie auf 0.
Stan
Der Compiler sollte dieses Konstrukt nicht zulassen, wenn es sich anders verhält als es ein vernünftiger Programmierer erwarten würde ... imho
cph2117
1
@ cph2117 Ein vernünftiger Programmierer würde denken, 'hmm, diese Syntax könnte ein paar verschiedene Dinge bedeuten, abhängig davon, wie die Grammatik die Dinge bindet' , den Standard nachschlagen, um herauszufinden, was wahr ist, und damit weitermachen .
underscore_d
Hör auf damit. Es macht Code nur schwerer zu lesen. Der Zweck des Schreibens von Code in einer Hochsprache besteht darin, dem Betreuer das Lesen zu erleichtern.
Martin York

Antworten:

202
int column = 0, row = 0, index = 0;
Josh
quelle
161

Wenn Sie erklären:

int column, row, index = 0;

Nur der Index wird auf Null gesetzt.

Sie können jedoch Folgendes tun:

int column, row, index;
column = index = row = 0;

Aber ich persönlich bevorzuge Folgendes, worauf hingewiesen wurde.
Meiner Ansicht nach ist es eine besser lesbare Form.

int column = 0, row = 0, index = 0;

oder

int column = 0;
int row = 0;
int index = 0;
Matt
quelle
3
Zwischen den letzten beiden entscheide ich mich basierend darauf, ob die beiden Werte wirklich vom selben Typ sein müssen ( bool previousInputValue, presentInputValue;) oder ob sie jetzt zufällig vom selben Typ sind, aber nicht wirklich sein müssen ( uint8_t height, width;möglicherweise uint8_t height; uint16_t width;in der Zukunft werden und sollten uint8_t height; uint8_t width;zunächst).
Altendky
Weil das Schreiben uint8_t height; uint16_t width;statt uint8_t height, width;10 Zeichen in der Zukunft spart. :-) du kannst es natürlich machen wie du willst. Stellen Sie einfach sicher, dass Sie es leicht lesbar machen. Die letzte Form ist also die expliziteste.
Matt
Die letzte Form ist sicherlich die expliziteste, wenn es darum geht, den Typ jeder Variablen anzugeben und deutlich zu machen, dass jede Variable initialisiert ist. Es ist jedoch nicht explizit angegeben, ob Spalte und Zeile vom selben Typ sein sollen oder nicht. Vielleicht würden wir beide die explizite Aussage von bevorzugen int presentValue = 0; typeof(presentValue) previousValue = presentValue;, aber ich glaube, dass dies typeof()eine nicht standardmäßige GCC-Erweiterung ist.
Altendky
49

Wie @Josh sagte, lautet die richtige Antwort:

int column = 0,
    row = 0,
    index = 0;

Sie müssen mit Zeigern auf dasselbe achten. Dies:

int* a, b, c;

Ist äquivalent zu:

int *a;
int b;
int c;
Mateen Ulhaq
quelle
34
Ich hasse diese Zeigersache, es macht keinen Sinn. Das Sternchen ist Teil des Typs und sollte daher für alle gelten. Stellen Sie sich vor unsigned long x, y;, xals deklariert als unsigned longaber yals gerecht unsigned, aka unsigned int! Das ist genau das gleiche! </ rant>
Cam Jackson
6
Es ergibt Sinn. "int * a, b, c;"
Jeroen
7
@JeroenBollen Nun ja, es ist sinnvoll, wenn Sie Ihre Zeiger-Sternchen neben den Variablennamen anstelle des Typs schreiben, aber das allein macht keinen Sinn. Wie ich oben sagte, ist das Sternchen Teil des Typs, nicht Teil des Namens, also sollte es mit dem Typ gruppiert werden!
Cam Jackson
11
Als Seite nicht, eigentlich macht es Sinn, dass das * nicht unbedingt Teil des Typs ist, als das int *aMittel, *adas einen intWert darstellt.
Mdenton8
2
Der Punkt wurde bereits gemacht, aber nur um ihn nichtig zu machen, ist im Wesentlichen das Fehlen eines Typs, aber Sie können trotzdem Zeiger darauf machen. Warum also void* akompilieren und void *a, b, cnicht kompilieren . Diese Rationalisierung funktioniert bei mir.
Josh C
24

Wenn Sie eine Variable / ein Objekt pro Zeile deklarieren, wird nicht nur dieses Problem gelöst, sondern der Code wird auch klarer und es werden dumme Fehler beim Deklarieren von Zeigern vermieden.

Um Ihre Frage jedoch direkt zu beantworten, müssen Sie jede Variable explizit auf 0 initialisieren. int a = 0, b = 0, c = 0;.

Mark B.
quelle
16
int column(0), row(0), index(0);

Beachten Sie, dass dieses Formular auch mit benutzerdefinierten Typen funktioniert, insbesondere wenn deren Konstruktoren mehr als ein Argument verwenden.

Michael Kristofik
quelle
2
und heutzutage mit einheitlicher Initialisierung (bis C ++ 17 dies für auto... behebt): int Spalte { 0 } , Zeile { 0 } , Index { 0 } ;
underscore_d
5

Ab 2k18 können Sie strukturierte Bindungen verwenden :

#include <iostream>
#include <tuple>

int main () 
{
    auto [hello, world] = std::make_tuple("Hello ", "world!");
    std::cout << hello << world << std::endl;
    return 0;
}

Demo

ivaigult
quelle
4

Mögliche Ansätze:

  • Initialisieren Sie alle lokalen Variablen mit Null.
  • Haben Sie ein Array memsetoder {0}das Array.
  • Machen Sie es global oder statisch.
  • Fügen Sie sie ein structund memsetoder haben Sie einen Konstruktor, der sie auf Null initialisiert.
Ajay
quelle
#define COLUMN 0 #define ROW 1 #define INDEX 2 #define AR_SIZE 3 int Data [ AR_SIZE ]; // Nur eine Idee.
Ajay
Entschuldigung, ich meinte, warum haben Sie die Zeile " Haben Sie ein Array, ein Memset oder {0} das Array. " In Ihre Antwort aufgenommen?
Mateen Ulhaq
Memset (Daten, 0, Größe von (Daten)); // Wenn dies logisch gepackt werden kann.
Ajay
2

Ich würde dies nicht empfehlen, aber wenn Sie es wirklich mögen, eine Zeile zu sein und nur einmal 0 zu schreiben, können Sie dies auch tun:

int row, column, index = row = column = 0;
Levi Uzodike
quelle
0

Wie bereits erwähnt, können Sie ab C ++ 17 strukturierte Bindungen für mehrere Variablenzuweisungen verwenden.

Dies mit Kombinieren std::arrayund Template - Argument Abzug wir eine Funktion , dass ein Wert zugewiesen einer beliebigen Anzahl von Variablen schreiben kann , ohne Wiederholung der Art oder Wert .

#include <iostream>
#include <array>

template <int N, typename T> auto assign(T value)
{
    std::array<T, N> out;
    out.fill(value);
    return out;
}

int main()
{
    auto [a, b, c] = assign<3>(1);

    for (const auto& v : {a, b, c})
    {
        std::cout << v << std::endl;
    }

    return 0;
}

Demo

jb
quelle
-13

Wenn Sie eine Variable deklarieren, ohne sie zu initialisieren, wird eine Zufallszahl aus dem Speicher ausgewählt und die Variable auf diesen Wert initialisiert.

user3487742
quelle
7
nicht wirklich. Der Compiler entscheidet, dass sich diese Variable an der Adresse xxx befindet. Was auch immer sich an der Adresse xxx befindet, ist der Anfangswert, es sei denn, es wird explizit (durch Initialisierung oder Zuweisung) auf etwas gesetzt
pm100
3
@ pm100 ist zwar besser und gilt für jede triviale Implementierung, die Benutzer nicht belästigt ... das ist immer noch zu einfach ;-) Da die Verwendung einer nicht initialisierten Variablen UB ist, kann theoretisch alles passieren, einschließlich Code Die Verwendung dieser Variablen wird einfach aus dem Programm entfernt - was besonders wahrscheinlich ist, wenn die Optimierung im Spiel ist.
underscore_d
1
Der Wert dieser Variablen wäre der Wert an der Adresse, die sie erhalten hat, dh Junk.
Pedro Vernetti
@PedroVernetti Es spielt keine Rolle, was sich an dieser Adresse befand, bevor die neue Variable deklariert wurde und zufällig dieselbe Adresse erhielt. Wenn der Benutzer die neue Variable deklariert, ohne sie mit einem Wert zu initialisieren, und dann die Variable liest, bevor er ihr einen Wert zugewiesen hat, hat das Programm ein undefiniertes Verhalten. Das ist unendlich schlimmer als "zufällig" und "Junk" und muss nur vermieden werden.
underscore_d