1104 votes

Comment initialiser un tableau en C

J'ai un grand tableau en C (pas en C++ si cela fait une différence). Je veux initialiser tous les membres à la même valeur. Je pourrais jurer que j'ai déjà connu un moyen simple de le faire. Je pouvais utiliser memset() dans mon cas, mais n'y a-t-il pas un moyen de le faire qui soit intégré à la syntaxe C ?

24 votes

Aucune des réponses jusqu'à présent ne mentionne la notation de l'initialisateur désigné qui est réalisable avec C99 et plus. Par exemple : enum { HYDROGEN = 1, HELIUM = 2, CARBON = 6, NEON = 10, … }; y struct element { char name[15]; char symbol[3]; } elements[] = { [NEON] = { "Neon", "Ne" }, [HELIUM] = { "Helium", "He" }, [HYDROGEN] = { "Hydrogen", "H" }, [CARBON] = { "Carbon", "C" }, … }; . Si vous enlevez le point de suspension ces fragments compilent sous C99 ou C11.

0 votes

En fait, la réponse d'abelenky utilise un initialisateur désigné, mais le code d'initialisation n'est pas entièrement formé.

0 votes

Memset() peut aider, mais cela dépend de la valeur.

1409voto

aib Points 18608

À moins que cette valeur ne soit 0 (auquel cas vous pouvez omettre une partie de l'initialisateur et les éléments correspondants seront initialisés à 0), il n'y a pas de moyen simple.

Mais ne négligez pas la solution la plus évidente :

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };

Les éléments avec des valeurs manquantes seront initialisés à 0 :

int myArray[10] = { 1, 2 }; //initialize to 1,2,0,0,0...

Cela va donc initialiser tous les éléments à 0 :

int myArray[10] = { 0 }; //all elements 0

En C++, une liste d'initialisation vide initialisera également chaque élément à 0 :

int myArray[10] = {}; //all elements 0 in C++

N'oubliez pas que les objets ayant une durée de stockage statique seront initialisés à 0 si aucun initialisateur n'est spécifié :

static int myArray[10]; //all elements 0

Et que "0" ne signifie pas nécessairement "tous-bits-zéro", donc utiliser ce qui précède est mieux et plus portable que memset(). (Les valeurs à virgule flottante seront initialisées à +0, les pointeurs à la valeur nulle, etc.)

30 votes

En lisant la norme C++, vous pouvez aussi faire int array[10] = {} ; pour initialiser le zéro. Je n'ai pas la norme C pour vérifier que c'est également valable pour le C.

58 votes

En regardant la section 6.7.8 Initialisation de la norme C99, il ne semble pas qu'une liste d'initialisation vide soit autorisée.

9 votes

C99 a beaucoup de fonctionnalités intéressantes pour l'initialisation des structures et des tableaux ; la seule fonctionnalité qu'il n'a pas (mais Fortran IV, 1966, l'avait) est un moyen de répéter un initialisateur particulier pour un tableau.

445voto

qrdl Points 17813

Si votre compilateur est GCC, vous pouvez utiliser la syntaxe suivante :

int array[1024] = {[0 ... 1023] = 5};

Consultez la description détaillée : http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html

0 votes

@qrdl J'ai essayé d'initialiser un tableau 2D alloué dynamiquement sur le tas en utilisant malloc(sizeof(int [row][col])) et j'ai obtenu une erreur de compilation à la ligne où est utilisée cette ligne : arr[row][col] = {[0 ... row -1] [0 ... col-1] = -1} ; L'erreur que j'ai obtenue était "expected expression before '{' token" Une idée à ce sujet ? Merci

2 votes

@abhi Ce que vous essayez de faire n'est pas une initialisation mais une affectation, cette syntaxe ne peut pas être utilisée dans une telle situation, vous serez mieux en utilisant memset()

0 votes

@qrdl merci pour la réponse donc en gros pour l'allocation dynamique je ne peux pas utiliser cette technique. correct ?

194voto

mouviciel Points 36624

Pour initialiser statiquement un grand tableau avec la même valeur, sans faire de multiples copier-coller, vous pouvez utiliser des macros :

#define VAL_1X     42
#define VAL_2X     VAL_1X,  VAL_1X
#define VAL_4X     VAL_2X,  VAL_2X
#define VAL_8X     VAL_4X,  VAL_4X
#define VAL_16X    VAL_8X,  VAL_8X
#define VAL_32X    VAL_16X, VAL_16X
#define VAL_64X    VAL_32X, VAL_32X

int myArray[53] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };

Si vous devez modifier la valeur, vous devez effectuer le remplacement à un seul endroit.

13 votes

Je ne l'envisagerais que dans des cas extrêmes, un memset est sûrement la manière la plus élégante de l'exprimer.

0 votes

Bien sûr, memset() est la solution. J'ai compris que l'OP cherchait une alternative.

51 votes

Si les données doivent être ROM-ables, memset ne peut pas être utilisé.

64voto

Frank Szczerba Points 2767

Si vous voulez vous assurer que chaque membre du tableau est explicitement initialisé, il suffit d'omettre la dimension dans la déclaration :

int myArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

Le compilateur déduira la dimension à partir de la liste des initialisateurs. Malheureusement, pour les tableaux multidimensionnels, seule la dimension la plus extérieure peut être omise :

int myPoints[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

est OK, mais

int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

ne l'est pas.

0 votes

Est-ce correct ? int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

12 votes

Non. Vous omettez la dimension la plus intérieure, ce qui n'est pas autorisé. Cela entraînera une erreur du compilateur.

4 votes

Les initialisateurs et l'inférence de longueur ont été introduits en C99.

57voto

abelenky Points 28063

J'ai vu un code qui utilisait cette syntaxe :

char* array[] = 
{
    [0] = "Hello",
    [1] = "World"
};   

Cela devient particulièrement utile si vous créez un tableau qui utilise des enums comme index :

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

#define _ITEM(x) [x] = #x

char* array[] = 
{
    _ITEM(ERR_OK),
    _ITEM(ERR_FAIL),
    _ITEM(ERR_MEMORY)
};   

Cela permet de conserver l'ordre des choses, même si vous écrivez certaines valeurs d'enum dans le désordre.

Pour en savoir plus sur cette technique, voir ici et ici .

9 votes

Il s'agit de la syntaxe d'initialisation C99, déjà couverte par certaines des autres réponses. Vous pourriez utilement transformer la déclaration en char const *array[] = { ... }; ou même char const * const array[] = { ... }; n'est-ce pas ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X