web-dev-qa-db-fra.com

valeur initiale du tableau int en C

Lors de la déclaration d'un tableau en C comme ceci:

int array[10];

Quelle est la valeur initiale des entiers ?? J'obtiens des résultats différents avec différents compilateurs et je veux savoir si cela a quelque chose à voir avec le compilateur ou le système d'exploitation.

43
buzali

Si le tableau est déclaré dans une fonction, la valeur n'est pas définie. int x[10]; dans une fonction signifie: prendre possession de la zone de taille 10 de memroy sans effectuer d'initialisation. Si le tableau est déclaré comme global ou comme static dans une fonction, alors tous les éléments sont initialisés à zéro s'ils ne sont pas déjà initialisés.

61
AraK

Comme défini par la norme, toutes les variables statiques globales et fonction sont automatiquement initialisées à 0. Les variables automatiques ne sont pas initialisées.

int a[10];  // global - all elements are initialised to 0

void foo(void) {
    int b[10];    // automatic storage - contain junk
    static int c[10]; // static - initialised to 0
}

Cependant, il est recommandé d'initialiser toujours manuellement la variable de fonction, quelle que soit sa classe de stockage. Pour mettre tous les éléments du tableau à 0, il vous suffit d'attribuer le premier élément du tableau à 0 - les éléments omis seront automatiquement mis à 0:

int b[10] = {0};
20
qrdl

Pourquoi les sections locales de fonction (auto classe de stockage) ne sont-elles pas initialisées alors que tout le reste l'est?

C est proche du matériel; c'est sa plus grande force et son plus grand danger. La raison pour laquelle les objets de classe de stockage auto ont des valeurs initiales aléatoires est parce qu'ils sont alloués sur la pile, et une décision de conception a été prise pour ne pas les effacer automatiquement (en partie parce qu'ils devraient être effacés à chaque appel de fonction).

En revanche, les objets nonauto ne doivent être effacés qu'une seule fois. De plus, le système d'exploitation doit de toute façon effacer les pages allouées pour des raisons de sécurité. La décision de conception a donc été de spécifier une initialisation nulle. Pourquoi la sécurité n'est-elle pas également un problème avec la pile? En fait, il est effacé, au début. Les fichiers indésirables que vous voyez proviennent d'instances antérieures des trames d'appel de votre propre programme et du code de bibliothèque qu'ils ont appelé.

Le résultat final est un code rapide et efficace en mémoire. Tous les avantages de l'assemblage sans aucune douleur. Avant que dmr n'invente le C, les "HLL" comme les noyaux OS de base et entiers étaient vraiment, littéralement, implémentés comme des programmes d'assembleurs géants. (Avec certaines exceptions dans des endroits comme IBM.)

12
DigitalRoss

Selon la norme C, 6.7.8 (note 10):

Si un objet qui a une durée de stockage automatique n'est pas initialisé explicitement, sa valeur est indéterminée.

Cela dépend donc du compilateur. Avec MSVC, les versions de débogage initialiseront les variables automatiques avec 0xcc, tandis que les versions sans débogage n'initialiseront pas du tout ces variables.

7
MSN

Une déclaration de variable C indique simplement au compilateur de mettre de côté et de nommer une zone de mémoire pour vous. Pour les variables automatiques, également appelées variables de pile, les valeurs de cette mémoire ne sont pas modifiées par rapport à ce qu'elles étaient auparavant. Les variables globales et statiques sont mises à zéro au démarrage du programme.

Certains compilateurs en mode de débogage non optimisé définissent les variables automatiques à zéro. Cependant, il est devenu courant dans les nouveaux compilateurs de définir les valeurs sur une mauvaise valeur connue afin que le programmeur n'écrive pas sans le savoir du code qui dépend de la définition d'un zéro.

Afin de demander au compilateur de mettre un tableau à zéro pour vous, vous pouvez l'écrire comme:

int array[10] = {0};

Mieux encore est de définir le tableau avec les valeurs qu'il devrait avoir. C'est plus efficace et évite d'écrire deux fois dans le tableau.

5
Zan Lynx

Dans la plupart des compilateurs les plus récents (par exemple, gcc/vc ++), les membres de la structure/tableau local partiellement initialisés sont initialisés par défaut à zéro (int), NULL (chaîne char/char), 0.000000 (float/double).

Outre les données de tableau/structure locales comme ci-dessus, les membres de l'espace statique (global/local) et global conservent également la même propriété.

int a[5] = {0,1,2};
printf("%d %d %d\n",*a, *(a+2), *(a+4));

struct s1
{
int i1;
int i2;
int i3;
char c;
char str[5];
};

struct s1 s11 = {1};
    printf("%d %d %d %c %s\n",s11.i1,s11.i2, s11.i3, s11.c, s11.str);
    if(!s11.c)
        printf("s11.c is null\n");
    if(!*(s11.str))
        printf("s11.str is null\n");

Dans gcc/vc ++, la sortie devrait être:

0 2 0 1 0 0 0.000000 s11.c est nul s11.str est nul

4
mav_2k

Texte de http://www.cplusplus.com/doc/tutorial/arrays/

SOMMAIRE:

Initialisation des tableaux. Lors de la déclaration d'un tableau régulier de portée locale (dans une fonction, par exemple), si nous ne spécifions pas le contraire, ses éléments ne seront initialisés à aucune valeur par défaut, donc leur contenu sera indéterminé jusqu'à ce que nous y stockions une valeur. Les éléments des tableaux globaux et statiques, en revanche, sont automatiquement initialisés avec leurs valeurs par défaut, ce qui signifie que pour tous les types fondamentaux, ils sont remplis de zéros.

Dans les deux cas, local et global, lorsque nous déclarons un tableau, nous avons la possibilité d'assigner des valeurs initiales à chacun de ses éléments en enfermant les valeurs entre accolades {}. Par exemple:

int billy [5] = { 16, 2, 77, 40, 12071 };
3
adatapost

Les sections pertinentes de la norme C (je souligne):

5.1.2 Environnements d'exécution

Tous les objets avec stockage statique durée doivent être initialisés (définis sur leurs valeurs initiales) avant le démarrage du programme.

6.2.4 Durées de stockage des objets

Un objet dont l'identifiant est déclaré avec une liaison externe ou interne, ou avec le spécificateur de classe de stockage statique a stockage statique durée.

6.2.5 Types

Array et les types de structure sont appelés collectivement agrégat types.

6.7.8 Initialisation

Si un objet qui a stockage automatique la durée est non initialisé explicitement , son la valeur est indéterminée . Si un objet qui a stockage statique la durée est non initialisé explicitement , puis :

  • s'il a un type de pointeur, il est initialisé à un pointeur nul;
  • s'il a un type arithmétique, il est initialisé à (positif ou non signé) zéro;
  • s'il s'agit d'un agrégat, chaque membre est initialisé (récursivement) selon ces règles;
  • s'il s'agit d'une union, le premier membre nommé est initialisé (récursivement) selon ces règles.
1
sergej