web-dev-qa-db-fra.com

Initialisation des variables en C

Je sais que parfois, si vous n'initialisez pas une int, vous obtiendrez un nombre aléatoire si vous imprimez le nombre entier.

Mais tout initialiser à zéro semble un peu idiot.

Je pose la question parce que je commente mon projet C et que je suis assez clair sur le retrait et que la compilation est complète (merci à Stackoverflow 90/90), mais je veux obtenir 10/10 sur les points de style. 

Donc, la question: quand faut-il initialiser et quand faut-il simplement déclarer une variable:

int a = 0;

contre. 

int a;
19
Arthur Collé

Voici une règle qui n'a pas encore été mentionnée: lorsque la variable est déclarée dans une fonction, elle n'est pas initialisée et lorsqu'elle est déclarée dans une portée statique ou globale, elle est définie sur 0

int a; // is set to 0

void foo() {
  int b;  // set to whatever happens to be in memory there
}

Cependant, pour des raisons de lisibilité, je commence généralement par tout initialiser au moment de la déclaration. 

Si vous souhaitez apprendre ce genre de chose en détail, je recommanderais cette présentation et ce livre

24
Timothy Jones

Il y a plusieurs circonstances où vous ne devriez pas initialiser une variable:

  1. Lorsqu'il a une durée de stockage statique (mot-clé static ou variable globale) et que vous voulez que la valeur initiale soit égale à zéro. La plupart des compilateurs vont en fait stocker des zéros dans le binaire si vous initialisez explicitement, ce qui n’est en général qu’un gaspillage d’espace (peut-être un énorme gaspillage pour les tableaux de grande taille).
  2. Lorsque vous passerez immédiatement l'adresse de la variable à une autre fonction qui remplit sa valeur. Dans ce cas, l’initialisation n’est qu’une perte de temps et peut prêter à confusion pour les lecteurs du code qui se demandent pourquoi vous stockez quelque chose dans une variable sur le point d’être écrasée.
  3. Lorsqu'une valeur significative pour la variable ne peut pas être déterminée avant l'exécution du code suivant. Dans ce cas, il est particulièrement préjudiciable d’initialiser la variable avec une valeur factice telle que zéro/NULL, car ceci empêche le compilateur de vous avertir} si vous avez des chemins de code dans lesquels une valeur explicite n’est jamais attribuée. Les compilateurs savent bien vous avertir de l'accès aux variables non initialisées, mais ne peuvent pas vous avertir des variables "contient encore des valeurs factices".

En plus de ces problèmes, je dirais que c'est généralement une bonne pratique d'initialiser vos variables non statiques lorsque cela est possible.

33
R..

Les variables statiques et globales seront initialisées à zéro pour que vous puissiez ignorer l'initialisation. Les variables automatiques (par exemple, les variables non statiques définies dans le corps de la fonction) peuvent contenir des ordures et devraient probablement toujours être initialisées.

Si vous avez besoin d'une valeur spécifique non nulle à l'initialisation, vous devez toujours l'initialiser explicitement. 

5
Adam Zalcman

Si la variable est dans le cadre d'une fonction et n'est pas membre d'une classe I toujours / initialisez-la, sinon vous obtiendrez des avertissements. Même si cette variable sera utilisée plus tard, je préfère l’affecter à la déclaration. 

En ce qui concerne les variables membres, vous devez les initialiser dans le constructeur de votre classe.

Pour les pointeurs, always initialise-les à certains paramètres par défaut, en particulier NULL, même s'ils doivent être utilisés ultérieurement, ils sont dangereux lorsqu'ils ne sont pas initialisés.

En outre, il est recommandé de construire votre code avec le plus haut niveau d'avertissements pris en charge par votre compilateur, ce qui permet d'identifier les mauvaises pratiques et les erreurs potentielles.

5
anio

Je peux penser à quelques raisons qui me viennent à l’esprit:

  1. Quand vous allez l'initialiser plus tard dans votre code.

    int x;
    
    if(condition)
    {
        func();
        x = 2;
    }
    else
    {
       x = 3;
    }
    anotherFunc(x); // x will have been set a value no matter what
    
  2. Lorsque vous avez besoin de mémoire pour stocker une valeur définie par une fonction ou un autre morceau de code:

    int x;  // Would be pointless to give x a value here
    scanf("%d", &x);
    
4
Tim Cooper

C'est toujours une bonne pratique d'initialiser vos variables, mais parfois ce n'est pas strictement nécessaire. Considérer ce qui suit:

int a;
for (a = 0; a < 10; a++) { } // a is initialized later

ou

void myfunc(int& num) {
  num = 10;
}

int a;
myfunc(&a); // myfunc sets, but does not read, the value in a

ou

char a;
cin >> a; // perhaps the most common example in code of where
          // initialization isn't strictly necessary

Ce ne sont là que quelques exemples où il n'est pas strictement nécessaire d'initialiser une variable, car elle est définie ultérieurement (mais n'est pas utilisée entre déclaration et initialisation).

En général cependant, il n’est pas inutile d’initialiser toujours vos variables lors de la déclaration (et c’est effectivement une pratique exemplaire).

3
Jared Ng

En général, il n'est pas nécessaire d'initialiser une variable, à deux exceptions notables près:

  1. Vous déclarez un pointeur (et ne l'attribuez pas immédiatement) - vous devez toujours définir ces valeurs sur NULL comme étant un bon style et une bonne programmation défensive. 
  2. Si, lorsque vous déclarez la variable, vous connaissez déjà quelle valeur va lui être attribuée. D'autres affectations utilisent plus de cycles du processeur.

Au-delà de cela, il s'agit de placer les variables dans le bon état dans lequel vous les souhaitez pour l'opération que vous allez effectuer. Si vous n'allez pas les lire avant qu'une opération ne change de valeur (et que l'opération ne tient pas compte de l'état dans lequel elle se trouve), il n'est pas nécessaire de les initialiser.

Personnellement, j'aime toujours les initialiser quand même; Si vous avez oublié de lui attribuer une valeur et que celle-ci est passée à une fonction par erreur (comme une longueur de mémoire tampon restante), 0 est généralement traité proprement - 32532556 ne le serait pas.

2
septical

Il n'y a absolument aucune raison pour que les variables ne soient pas initialisées, le compilateur est suffisamment intelligent pour ignorer la première affectation si une variable est affectée deux fois. Il est facile pour le code de croître en taille lorsque les éléments que vous tenez pour acquis (tels que l'affectation d'une variable avant d'être utilisée) ne sont plus vrais. Considérer:

int MyVariable;
void Simplistic(int aArg){
    MyVariable=aArg;
}

//Months later:

int MyVariable;
void Simplistic(int aArg){
    MyVariable+=aArg; // Unsafe, since MyVariable was never initialized.
}

L'un va bien, l'autre vous pose beaucoup de problèmes. Il arrive parfois que votre application s'exécute en mode débogage, mais le mode de publication génère une exception, en raison de l'utilisation d'une variable non initialisée.

2
R4D4

Tant que je n'ai pas lu de variable avant d'y écrire, je n'ai pas eu à m'inquiéter de l'initialiser.

Lire avant d'écrire peut causer des problèmes sérieux et difficiles à attraper. Je pense que cette classe de bugs est assez notoire pour être mentionnée dans les vidéos de conférences populaires du SICP.

1
vpit3833

L'initialisation d'une variable, même si elle n'est pas strictement requise, est TOUJOURS une bonne pratique. Les quelques caractères supplémentaires (tels que "= 0") saisis au cours du développement peuvent économiser des heures de temps de débogage, en particulier lorsque vous oubliez que certaines variables restent non initialisées. 

En passant, j'estime qu'il est bon de déclarer une variable proche de son utilisation .

Ce qui suit est mauvais:

int a;    // line 30
...
a = 0;    // line 40

Ce qui suit est bon:

int a = 0;  // line 40

De plus, si la variable doit être écrasée juste après l’initialisation, comme

int a = 0;
a = foo();

il vaut mieux l'écrire comme

int a = foo();
0
Arun