Comment puis-je déclarer et définir plusieurs variables sur une seule ligne en utilisant C ++?


173

Je pense toujours que si je déclare ces trois variables, elles auront toutes la valeur 0

int column, row, index = 0;

Mais je trouve que seul l'index est égal à zéro et les autres sont indésirables comme 844553 et 2423445.

Comment puis-je initialiser toutes ces variables à zéro sans déclarer chaque variable sur une nouvelle ligne?


36
Attention à ces déclarations multi-variables sur une ligne. Il est plus facile que vous ne le pensez de déclarer un pointeur int suivi d'une liste d'entiers réguliers ( int* a, b, c;ne fait pas ce à quoi il ressemble).
Chris Eberle

4
Il n'y a que trois variables, mec, écrivez =0pour chacune dans leurs définitions. Et, si vous voulez vraiment beaucoup de variables, essayez un tableau: int a[10]={0}initialisera chacune a[i]à 0 pour vous.
Stan du

Le compilateur ne devrait pas autoriser cette construction si elle va se comporter différemment de ce qu'un programmeur raisonnable s'attendrait à ce qu'elle fasse ... à mon humble avis
cph2117

1
@ cph2117 Un programmeur raisonnable penserait 'hmm, cette syntaxe pourrait signifier plusieurs choses différentes selon la façon dont la grammaire lie les choses' , rechercher le Standard pour savoir ce qui est vrai et continuer avec.
underscore_d

Arrête de faire ça. Cela rend simplement le code plus difficile à lire. Le but d'écrire du code dans un langage de haut niveau est de le rendre simple à lire pour un responsable.
Martin York le

Réponses:



162

Lorsque vous déclarez:

int column, row, index = 0;

Seul l'index est mis à zéro.

Cependant, vous pouvez faire ce qui suit:

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

Mais personnellement, je préfère ce qui a été souligné.
C'est une forme plus lisible à mon avis.

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

ou

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

3
Entre les deux derniers, je décide en fonction de savoir si les deux valeurs doivent vraiment être du même type ( bool previousInputValue, presentInputValue;) ou si elles sont simplement du même type maintenant mais n'ont pas vraiment besoin de l'être ( uint8_t height, width;pourraient devenir uint8_t height; uint16_t width;dans le futur et auraient dû être uint8_t height; uint8_t width;pour commencer).
altendky

Parce que l'écriture uint8_t height; uint16_t width;au lieu de uint8_t height, width;sauve 10 caractères dans le futur. :-) vous pouvez bien sûr le faire comme vous le souhaitez. Assurez-vous simplement de le rendre facilement lisible. La dernière forme est donc la plus explicite.
Matt

La dernière forme est certainement la plus explicite pour indiquer le type de chaque variable et indiquer clairement que chacune est initialisée. Cela dit, il n'est pas explicite de savoir si la colonne et la ligne doivent être du même type ou non. Peut-être que nous préférerions tous les deux l'explicitation de int presentValue = 0; typeof(presentValue) previousValue = presentValue;, mais je crois que typeof()c'est une extension GCC non standard.
altendky

49

Comme l'a dit @Josh, la bonne réponse est:

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

Vous devrez faire attention à la même chose avec des pointeurs. Ce:

int* a, b, c;

Est équivalent à:

int *a;
int b;
int c;

34
Je déteste ce truc de pointeur, ça n'a aucun sens. L'astérisque fait partie du type, il devrait donc s'appliquer à tous. Imaginez si unsigned long x, y;déclaré xcomme unsigned longmais yaussi juste unsigned, aka unsigned int! C'est exactement la même chose! </rant>
Cam Jackson

6
Ca a du sens. "int * a, b, c;"
Jeroen le

7
@JeroenBollen Eh bien oui, cela a du sens si vous écrivez vos astérisques de pointeur à côté du nom de la variable au lieu du type, mais cela en soi n'a aucun sens. Comme je l'ai dit ci-dessus, l'astérisque fait partie du type, pas du nom, il devrait donc être regroupé avec le type!
Cam Jackson

11
En tant que non, en fait, il est logique que le * ne fasse pas nécessairement partie du type, car le int *amoyen *areprésente une intvaleur.
mdenton8

2
Le point a déjà été fait, mais juste pour y ajouter void, c'est essentiellement l'absence d'un type, mais vous pouvez toujours faire des pointeurs vers lui. Alors pourquoi void* acompilera et void *a, b, cne le fera pas. Cette rationalisation fonctionne pour moi.
Josh C

25

Si vous déclarez une variable / objet par ligne, non seulement cela résout ce problème, mais cela rend le code plus clair et évite les erreurs stupides lors de la déclaration des pointeurs.

Pour répondre directement à votre question, vous devez initialiser chaque variable à 0 explicitement. int a = 0, b = 0, c = 0;.


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

Notez que ce formulaire fonctionnera également avec les types personnalisés, en particulier lorsque leurs constructeurs acceptent plus d'un argument.


2
et de nos jours avec une initialisation uniforme (en attente de C ++ 17 corrigeant cela pour auto...): int colonne { 0 } , ligne { 0 } , index { 0 } ;
underscore_d

5

À partir de 2k18, vous pouvez utiliser des liaisons structurées :

#include <iostream>
#include <tuple>

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

Demo


4

Approches possibles:

  • Initialisez toutes les variables locales avec zéro.
  • Avoir un tableau, memsetou {0}le tableau.
  • Rendez-le global ou statique.
  • Mettez-les dans struct, et / memsetou ayez un constructeur qui les initialiserait à zéro.

#define COLUMN 0 #define ROW 1 #define INDEX 2 #define AR_SIZE 3 int Données [ AR_SIZE ]; // Juste une idée.
Ajay

Pardon, je voulais dire, pourquoi avez-vous inclus la ligne " Avoir un tableau, un memset ou {0} le tableau. " Dans votre réponse?
Mateen Ulhaq

memset (Données, 0, sizeof (Données)); // Si cela peut être compressé logiquement.
Ajay

2

Je ne recommanderais pas cela, mais si vous aimez vraiment le fait d'être une ligne et d'écrire 0 une fois seulement, vous pouvez également le faire:

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

0

Comme d'autres l'ont mentionné, à partir de C ++ 17, vous pouvez utiliser des liaisons structurées pour plusieurs affectations de variables.

En combinant cela std::arrayet déduction des arguments de modèle , nous pouvons écrire une fonction qui attribue une valeur à un nombre arbitraire de variables sans répéter le type ou la valeur .

#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

Lorsque vous déclarez une variable sans l'initialiser, un nombre aléatoire de la mémoire est sélectionné et la variable est initialisée à cette valeur.


7
pas vraiment. Le compilateur décide que `` cette variable sera à l'adresse xxx '', tout ce qui se trouve à l'adresse xxx sera la valeur initiale à moins qu'elle ne soit définie explicitement (par initialisation ou affectation)
pm100

3
@ pm100 bien que meilleur , et vrai pour toute implémentation triviale qui ne fait pas tout son possible pour harceler les utilisateurs ... cela simplifie encore trop ;-) car l'utilisation d'une variable non initialisée est UB, donc en théorie tout peut arriver, y compris n'importe quel code en utilisant cette variable simplement en étant supprimée du programme - ce qui est particulièrement probable lorsque l'optimisation est en cours.
underscore_d

1
la valeur de cette variable serait ce qui se trouve à l'adresse qu'elle a obtenue, c'est-à-dire indésirable.
Pedro Vernetti du

@PedroVernetti Peu importe ce qui s'est passé à ladite adresse avant que la nouvelle variable ne soit déclarée et n'obtienne la même adresse. Si l'utilisateur déclare la nouvelle variable sans l'initialiser avec une valeur, puis lit la variable avant de lui avoir assigné une valeur, le programme a un comportement indéfini. C'est infiniment pire que «aléatoire» et «indésirable» et doit juste être évité.
underscore_d
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.