2017-01-29 4 views
3

Dans le langage C, estInitialiser toutes les variables C dans une ligne et de la valeur non initialisée

int x, y, z = 0; 

la même chose que cela?

int x = 0; 
int y = 0; 
int z = 0; 

De plus, si je dis simplement int a;, il semble que la valeur de a est égal à zéro, même si elle est non initialisée, mais pas définie comme décrit dans What will be the value of uninitialized variable?

+0

dépend de l'action du compilateur. –

+0

Vous auriez probablement dû poser les deux questions séparément. – Clifford

Répondre

4

Non les deux ne sont pas équivalents.

int x, y, z = 0; 

Dans cette ligne x et y aura une valeur indéterminée, alors que z est initialisé à zéro.

Vous pouvez cependant le conserver dans « une ligne » pour le prix d'une verbosité:

int x = 0, y = x, z = y; 

Maintenant, tous les trois sont initialisés avec la même valeur (celle que vous avez donné x). Pour initialiser une variable avec une autre, tout ce qui est requis est que l'initialiseur soit préalablement défini. Et cela fonctionne même si c'est sur la même ligne. Ce qui précède vous permettra également de modifier assez facilement la valeur initiale de toutes les variables.

Alternativement, si vous trouvez le style précédent laid, vous pouvez le faire fonctionner en deux lignes:

int x, y, z; 
x = y = z = 0; 

Mais il est maintenant l'affectation, et non d'initialisation.

De plus, si je dis simplement int a;, il semble que la valeur de a est égal à zéro, même si elle est non initialisée, mais pas non défini comme décrit dans Quelle sera la valeur de la variable non initialisée?

"Valeur indéterminée" ne signifie pas "non nul". Il n'y a rien à propos de zéro qui en fait un candidat invalide pour la valeur initiale des variables. Certains compilateurs "utiles" initialisent des variables d'initialisation dans les versions de débogage. Il peut cacher des bugs sinistres si vous ne tenez pas compte des avertissements du compilateur.

+0

'int x = 0, y = x, z = y;' a l'air vraiment moche et 'x = y = z = 0;' est l'assignation pas l'initialisation. 'int x = 0, y = 0, z = 0;' est propre et de la manière la plus préférée. – haccks

+0

@haccks - (* shurg *) d'accord. – StoryTeller

+0

Il est peut-être plus courant qu'un environnement * debug * remplisse simplement la pile avec zéro (ou une autre valeur spécifique) au démarrage plutôt que le compilateur fournissant une initialisation explicite, mais je n'ai jamais vérifié cette assertion pour tous les compilateurs/débogueurs. – Clifford

4

Ce:

int x, y, z = 0; 

n'est pas la même chose que

int x = 0, y = 0, z = 0; 

ou

int x = 0; 
int y = 0; 
int z = 0; 

Dans le premier cas que z seront réinitialisés alors que dans les deux derniers cas - tous Trois.

Si la valeur n'est pas initialisée, sa valeur est indéterminée et la lecture de la variable non initialisée est un comportement indéfini - et le fait qu'après lecture, elle semble avoir la valeur 0 est le résultat de undefined behavior.

2

Une déclaration comme

int x, y, z = 0; 

seule la dernière initialise variable z; x et y restent non initialisés.

Un équivalent possible de

int x = 0; 
int y = 0; 
int z = 0; 

serait

int x, y, z; 
x = y = z = 0; 

Cela dit,

De plus, si je dis simplement int a;, il semble que la valeur de a est zéro même s'il n'est pas initialisé

Cela dépend, si la variable a une durée de stockage statique, il sera implicitement être initialisé à 0.

+2

'x = y = z = 0;' est assignations, alors que l'ancien – haccks

+0

@haccks droite, c'est pourquoi j'ai écrit _equivalent_. :) –

0

La réponse à votre question poing est « non », seule la variable initialisées explicitement sera attribué. Les autres peuvent avoir n'importe quelle valeur, (y compris zéro).

Pour répondre à votre deuxième (plus intéressant) question (qui méritait peut-être une question distincte):

Le terme « unitialised » signifie simplement qu'aucune valeur est explicitement attribuée à l'instanciation; la valeur correspond à tout ce qui se trouve dans l'emplacement de mémoire associé à ce moment-là. Certains environnements remplissent la pile avec zéro au début de l'exécution, donc dans les exemples triviaux, zéro est probable. Cependant, cela ne sera pas toujours le cas lorsque la pile est retournée pendant l'exécution et contient des valeurs différentes du code précédemment exécuté.

Par exemple, dans ce qui suit, il est probable que a dans fn() ne sera pas nul pour chaque appel (ou peut-être un appel) et va changer entre les appels:

void fn() 
{ 
    static int i = 1 ; 
    volatile int a ; 
    printf("Call %d: a = %d\n", i, a) ; 
    i++ ; 
    a = i ; 
} 

int main() 
{ 
    for(int i = 0; i < 10; i++) 
    { 
     fn() ; 
    } 
} 

Dans mon test (à ideone. com), il génèrerait les éléments suivants:

Call 1: a = 134513970 
Call 2: a = 2 
Call 3: a = 3 
Call 4: a = 4 
Call 5: a = 5 
Call 6: a = 6 
Call 7: a = 7 
Call 8: a = 8 
Call 9: a = 9 
Call 10: a = 10 

Comme vous pouvez le voir dans les appels deuxième et les suivants qu'il contient tout ce qui a été laissé à cet endroit de l'appel précédent, car le même pile l'emplacement est réutilisé. Un modèle d'appel différent - par exemple, insérer un appel de fonction avant ou après fn() produira un résultat différent et moins prévisible lorsque cette zone de pile est réutilisée par d'autres fonctions. Par exemple, lorsque j'ai modifié le corps de la boucle comme suit:

 rand() ; 
     fn() ; 

Le résultat a été:

Call 1: a = 1433091188 
Call 2: a = 1433091188 
Call 3: a = 1433091188 
Call 4: a = 1433091188 
Call 5: a = 1433091188 
Call 6: a = 1433091188 
Call 7: a = 1433091188 
Call 8: a = 1433091188 
Call 9: a = 1433091188 
Call 10: a = 1433091188 
+0

Il serait préférable que vous mentionniez que dans ce cas, le comportement du programme pourrait être indéfini si cette variable est accédée et qu'il existe une représentation d'interruption pour cette variable. – haccks

+0

@haccks: Je devrais comprendre ce que vous proposiez avant de pouvoir le mentionner! La variable est * non initialisée *, la * valeur * d'une variable initialisée est * undefined *; Puisque toutes les 2^32 valeurs possibles de 'int' sont valides, je ne suis pas sûr de ce que vous entendez par" représentation de piège ". – Clifford

+0

@haccks: Ok - Je sais maintenant ce qu'est une "représentation de piège", mais comme je ne suis évidemment pas un expert, je ne devrais pas le mentionner du tout. Je doute en fait qu'il y ait une implémentation avec une telle représentation pour 'int' malgré la norme * qui l'autorise *. Je ne pense pas que le point affecte la validité de la réponse par omission; J'essaie simplement de démontrer qu'un exemple d'une variable unitialisée étant zéro ne signifie pas que toutes ces variables sont nulles. – Clifford