Come posso dichiarare e definire più variabili in una riga usando C ++?


173

Ho sempre pensato che se dichiaro queste tre variabili che avranno tutte il valore 0

int column, row, index = 0;

Ma trovo che solo l'indice sia uguale a zero e gli altri siano spazzatura come 844553 e 2423445.

Come posso inizializzare tutte queste variabili a zero senza dichiarare ogni variabile su una nuova riga?


36
Attento a quelle dichiarazioni multi-variabile a una riga. È più facile di quanto pensi di dichiarare un puntatore int seguito da un elenco di numeri interi regolari ( int* a, b, c;non fa quello che sembra).
Chris Eberle,

4
Ci sono solo tre variabili, amico, scrivono =0per ognuna nelle loro definizioni. E, se vuoi davvero molte variabili, prova un array: int a[10]={0}inizializzerai ciascuno a[i]a 0 per te.
Stan,

Il compilatore non dovrebbe consentire tale costrutto se si comporterà in modo diverso da quello che un programmatore ragionevole si aspetterebbe che faccia ... imho
cph2117

1
@ cph2117 Un programmatore ragionevole potrebbe pensare 'hmm, questa sintassi potrebbe significare un paio di cose diverse a seconda di come la grammatica lega le cose' , cercare lo Standard per scoprire quale sia la verità e andare avanti.
underscore_d

Smetti di farlo. Rende solo il codice più difficile da leggere. Il punto di scrivere codice in un linguaggio di alto livello è rendere semplice la lettura di un manutentore.
Martin York,

Risposte:


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

162

Quando dichiari:

int column, row, index = 0;

Solo l'indice è impostato su zero.

Tuttavia è possibile effettuare le seguenti operazioni:

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

Ma personalmente preferisco quanto segue che è stato sottolineato.
È una forma più leggibile dal mio punto di vista.

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

o

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

3
Tra gli ultimi due decido in base al fatto che i due valori debbano essere davvero dello stesso tipo ( bool previousInputValue, presentInputValue;) o se si trovano solo nello stesso tipo ora ma non è necessario che lo siano ( uint8_t height, width;potrebbe trasformarsi in uint8_t height; uint16_t width;futuro e avrebbe dovuto essere uint8_t height; uint8_t width;iniziare con).
Altendky,

Perché scrivere uint8_t height; uint16_t width;invece di uint8_t height, width;salvare 10 caratteri in futuro. Sorriso puoi ovviamente farlo come preferisci. Assicurati solo di farlo facilmente leggere. Quindi l'ultima forma è la più esplicita.
Matt

L'ultima forma è sicuramente la più esplicita nel dichiarare il tipo di ogni variabile e nel chiarire che ognuna è inizializzata. Detto questo, non è esplicito se ci si aspetta che colonne e righe siano dello stesso tipo o meno. Forse preferiremmo entrambi la spiegazione di int presentValue = 0; typeof(presentValue) previousValue = presentValue;, ma credo che typeof()sia un'estensione GCC non standard.
altendky,

49

Come ha detto @Josh, la risposta corretta è:

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

Dovrai fare attenzione alla stessa cosa con i puntatori. Questo:

int* a, b, c;

È equivalente a:

int *a;
int b;
int c;

34
Odio quella cosa puntatore, non ha senso. L'asterisco fa parte del tipo, quindi dovrebbe applicarsi a tutti loro. Immagina se unsigned long x, y;dichiarato xcome unsigned longma yanche solo unsigned, aka unsigned int! È esattamente lo stesso! </rant>
Cam Jackson il

6
Ha senso. "int * a, b, c;"
Jeroen,

7
@JeroenBollen Beh, sì, ha senso scrivere gli asterischi puntatore accanto al nome della variabile anziché al tipo, ma questo di per sé non ha alcun senso. Come ho detto sopra, l'asterisco fa parte del tipo, non parte del nome, quindi dovrebbe essere raggruppato con il tipo!
Cam Jackson,

11
D'altra parte, in realtà ha senso che il * non sia necessariamente parte del tipo, in quanto il int *amezzo che *arappresenta un intvalore.
mdenton8,

2
Il punto è già stato messo in evidenza, ma solo aggiungere ad esso nulla è essenzialmente la mancanza di un tipo, ma è ancora possibile indicarlo. Quindi perché void* acompilerà e void *a, b, cnon lo farà. Questa razionalizzazione funziona per me.
Josh C,

25

Se si dichiara una variabile / oggetto per riga non solo risolve questo problema, ma rende il codice più chiaro e previene errori stupidi quando si dichiarano i puntatori.

Per rispondere direttamente alla tua domanda, devi inizializzare ogni variabile su 0 in modo esplicito. int a = 0, b = 0, c = 0;.


16
int column(0), row(0), index(0);

Nota che questo modulo funzionerà anche con tipi personalizzati, specialmente quando i loro costruttori accettano più di un argomento.


2
e oggigiorno con inizializzazione uniforme (in attesa di C ++ 17 per risolvere questo problema per auto...): colonna int { 0 } , riga { 0 } , indice { 0 } ;
underscore_d

5

A partire da 2k18, è possibile utilizzare Associazioni strutturate :

#include <iostream>
#include <tuple>

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

Demo


4

Possibili approcci:

  • Inizializza tutte le variabili locali con zero.
  • Avere un array memseto{0} l'array.
  • Rendilo globale o statico.
  • Inseriscili structe memsetdisponi di un costruttore che li inizializzerebbe a zero.

#define COLUMN 0 #define ROW 1 #define INDEX 2 #define AR_SIZE 3 int Data [ AR_SIZE ]; // Solo un'idea.
Ajay,

Spiacenti, intendevo dire, perché hai incluso la riga " Disponi di un array, memset o {0} l'array " nella tua risposta?
Mateen Ulhaq,

memset (Dati, 0, sizeof (Dati)); // Se questo può essere impacchettato logicamente.
Ajay,

2

Non lo consiglierei, ma se ti piace davvero essere una riga e scrivere solo 0 una volta, puoi anche farlo:

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

0

Come altri hanno già detto, da C ++ 17 in poi è possibile utilizzare associazioni strutturate per più assegnazioni di variabili.

Combinando questo con std::arraye deduzione template argomento possiamo scrivere una funzione che assegna un valore a un numero arbitrario di variabili senza ripetere il tipo o valore .

#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


-13

Quando si dichiara una variabile senza inizializzarla, viene selezionato un numero casuale dalla memoria e la variabile viene inizializzata su quel valore.


7
non proprio. Il compilatore decide 'questa variabile sarà all'indirizzo xxx', qualunque cosa sia accaduta all'indirizzo xxx sarà il valore iniziale a meno che non sia impostata su qualcosa in modo esplicito (tramite inizializzazione o assegnazione)
pm100

3
@ pm100 anche se migliore , e vero per qualsiasi implementazione banale che non fa di tutto per molestare gli utenti ... questo è ancora troppo semplificato ;-) poiché l'uso di una variabile non inizializzata è UB, quindi in teoria tutto può succedere, incluso qualsiasi codice usare quella variabile semplicemente eliminando il programma, il che è particolarmente probabile quando è in gioco l'ottimizzazione.
underscore_d

1
il valore di quella variabile sarebbe qualunque fosse all'indirizzo che ha ottenuto, cioè junk.
Pedro Vernetti,

@PedroVernetti Non importa cosa sia accaduto a detto indirizzo prima che la nuova variabile fosse dichiarata e fosse capitato di ottenere lo stesso indirizzo. Se l'utente dichiara la nuova variabile senza inizializzarla con un valore e quindi legge la variabile prima di averle assegnato un valore, il programma ha un comportamento indefinito. È infinitamente peggio di "random" e "junk" e deve solo essere evitato.
underscore_d
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.