Comment initialiser tous les membres d'un tableau de la même valeur?

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

808
demandé sur Lundin 2008-10-14 17:13:40

18 réponses

sauf si cette valeur est 0 (auquel cas vous pouvez omettre une partie de l'initialiseur et les éléments correspondants seront initialisés à 0), Il n'y a pas de manière facile.

N'oubliez pas la solution évidente, cependant:

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...

donc ceci initialisera tous les éléments à 0:

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

en C++, Un vide liste d'initialisation va également initialiser chaque élément à 0. C'est non autorisé avec C:

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

rappelez-vous que les objets avec une durée de stockage statique s'initialiseront à 0 si non l'initialiseur est spécifié:

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

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

1056
répondu aib 2017-05-23 11:33:24

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

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

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

352
répondu qrdl 2009-10-13 22:43:06

pour l'initialisation statique d'un grand tableau avec la même valeur, sans copier-coller multiple, 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 avez besoin de changer la valeur, vous devez faire le remplacement à un seul endroit.

modifier: extensions utiles possibles

(gracieuseté de Jonathan Leffler )

vous pouvez facilement généraliser avec:

#define VAL_1(X) X
#define VAL_2(X) VAL_1(X), VAL_1(X)
/* etc. */

une variante peut être créée en utilisant:

#define STRUCTVAL_1(...) { __VA_ARGS__ }
#define STRUCTVAL_2(...) STRUCTVAL_1(__VA_ARGS__), STRUCTVAL_1(__VA_ARGS__)
/*etc */ 

qui fonctionne avec des structures ou des matrices composées.

#define STRUCTVAL_48(...) STRUCTVAL_32(__VA_ARGS__), STRUCTVAL_16(__VA_ARGS__)

struct Pair { char key[16]; char val[32]; };
struct Pair p_data[] = { STRUCTVAL_48("Key", "Value") };
int a_data[][4] = { STRUCTVAL_48(12, 19, 23, 37) };
Les noms de macros

sont négociables.

163
répondu mouviciel 2017-05-23 11:47:36

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

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

le compilateur déduira la dimension de la liste des initialiseurs. Malheureusement, pour les tableaux multidimensionnels, seule la dimension 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} };

n'est pas.

59
répondu Frank Szczerba 2008-10-14 18:30:25

j'ai vu un code qui utilisait cette syntaxe:

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

où il devient particulièrement utile est si vous faites un tableau qui utilise 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 maintient les choses en ordre, même si vous vous trouvez à écrire certaines des valeurs enum hors de l'ordre.

plus sur cette technique peut être trouvé ici et ici .

45
répondu abelenky 2012-03-22 18:34:31
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

je pense que c'est mieux que

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...

incrase la taille du tableau change.

22
répondu Tarski 2008-10-14 13:34:02

vous pouvez faire toute la chose static initializer comme détaillé ci-dessus, mais il peut être un vrai déception lorsque la taille de votre tableau change (lorsque votre tableau embiggens, si vous n'ajoutez pas les initialisateurs supplémentaires appropriés vous obtenez des ordures).

memset vous donne un hit runtime pour faire le travail, mais aucun hit de taille de code fait correctement est immunisé aux changements de taille de tableau. J'utiliserais cette solution dans presque tous les cas où le tableau était plus grand que, disons, quelques douzaines d'éléments.

S'il était vraiment important que le tableau soit statiquement déclaré, j'écrirais un programme pour écrire le programme pour moi et le faire partie du processus de construction.

11
répondu plinth 2008-10-14 13:29:25

Voici une autre façon:

static void
unhandled_interrupt(struct trap_frame *frame, int irq, void *arg)
{
    //this code intentionally left blank
}

static struct irqtbl_s vector_tbl[XCHAL_NUM_INTERRUPTS] = {
    [0 ... XCHAL_NUM_INTERRUPTS-1] {unhandled_interrupt, NULL},
};

voir:

C-Extensions

désignés inits

posez alors la question: Quand peut-on utiliser les extensions C?

l'échantillon de code ci-dessus est dans un système intégré et ne verra jamais la lumière d'un autre compilateur.

8
répondu humble_guru 2010-08-27 08:04:06

pour initialiser les types de données' normales '(comme les tableaux int), vous pouvez utiliser la notation bracket, mais elle mettra à zéro les valeurs après la dernière si il y a encore de l'espace dans le tableau:

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};
5
répondu warren 2008-10-14 13:17:39

Un peu la langue-dans-joue réponse; écrire l'instruction

array = initial_value

dans votre langage favori (le mien est Fortran, mais il y en a beaucoup d'autres), et liez-le à votre code C. Vous voudriez probablement l'emballer pour une fonction externe.

5
répondu High Performance Mark 2010-08-27 08:06:18

si le tableau se trouve être int ou quelque chose avec la taille de int ou la taille de votre mem-pattern correspond à des temps exacts dans un int (i.e. tous les zéros ou 0xA5A5A5A5), la meilleure façon est d'utiliser memset () .

sinon appelez memcpy() dans une boucle déplaçant l'index.

4
répondu ddimitrov 2008-10-25 12:43:00

il y a un moyen rapide d'initialiser le tableau de n'importe quel type avec la valeur donnée. Il fonctionne très bien avec les grands tableaux. L'algorithme est le suivant:

  • initialiser le premier élément du tableau (de la manière habituelle)
  • partie de copie qui a été réglée en partie qui n'a pas été réglée, doublant la taille à chaque opération de copie suivante

pour 1 000 000 elements int array c'est 4 temps plus rapides que l'initialisation de boucle régulière (i5, 2 cœurs, 2,3 GHz, Mémoire 4GiB, 64 bits):

loop runtime 0.004248 [seconds]

memfill() runtime 0.001085 [seconds]


#include <stdio.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 1000000

void memfill(void *dest, size_t destsize, size_t elemsize) {
   char   *nextdest = (char *) dest + elemsize;
   size_t movesize, donesize = elemsize;

   destsize -= elemsize;
   while (destsize) {
      movesize = (donesize < destsize) ? donesize : destsize;
      memcpy(nextdest, dest, movesize);
      nextdest += movesize; destsize -= movesize; donesize += movesize;
   }
}    
int main() {
    clock_t timeStart;
    double  runTime;
    int     i, a[ARR_SIZE];

    timeStart = clock();
    for (i = 0; i < ARR_SIZE; i++)
        a[i] = 9;    
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("loop runtime %f [seconds]\n",runTime);

    timeStart = clock();
    a[0] = 10;
    memfill(a, sizeof(a), sizeof(a[0]));
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("memfill() runtime %f [seconds]\n",runTime);
    return 0;
}
3
répondu Maciej 2015-10-03 11:59:20

personne n'a mentionné l'ordre d'index pour accéder aux éléments du tableau initialisé. Mon exemple de code lui servira d'exemple.

#include <iostream>

void PrintArray(int a[3][3])
{
    std::cout << "a11 = " << a[0][0] << "\t\t" << "a12 = " << a[0][1] << "\t\t" << "a13 = " << a[0][2] << std::endl;
    std::cout << "a21 = " << a[1][0] << "\t\t" << "a22 = " << a[1][1] << "\t\t" << "a23 = " << a[1][2] << std::endl;
    std::cout << "a31 = " << a[2][0] << "\t\t" << "a32 = " << a[2][1] << "\t\t" << "a33 = " << a[2][2] << std::endl;
    std::cout << std::endl;
}

int wmain(int argc, wchar_t * argv[])
{
    int a1[3][3] =  {   11,     12,     13,     // The most
                        21,     22,     23,     // basic
                        31,     32,     33  };  // format.

    int a2[][3] =   {   11,     12,     13,     // The first (outer) dimension
                        21,     22,     23,     // may be omitted. The compiler
                        31,     32,     33  };  // will automatically deduce it.

    int a3[3][3] =  {   {11,    12,     13},    // The elements of each
                        {21,    22,     23},    // second (inner) dimension
                        {31,    32,     33} };  // can be grouped together.

    int a4[][3] =   {   {11,    12,     13},    // Again, the first dimension
                        {21,    22,     23},    // can be omitted when the 
                        {31,    32,     33} };  // inner elements are grouped.

    PrintArray(a1);
    PrintArray(a2);
    PrintArray(a3);
    PrintArray(a4);

    // This part shows in which order the elements are stored in the memory.
    int * b = (int *) a1;   // The output is the same for the all four arrays.
    for (int i=0; i<9; i++)
    {
        std::cout << b[i] << '\t';
    }

    return 0;
}

la sortie est:

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

11      12      13      21      22      23      31      32      33
2
répondu hkBattousai 2016-02-22 07:58:43
  1. si votre tableau est déclaré statique ou global, tous les éléments dans le tableau ont déjà la valeur par défaut 0.
  2. certains compilateurs ont défini le tableau par défaut à 0 en mode de débogage.
  3. il est facile de définir la valeur par défaut à 0 : tableau int[10] = {0};
  4. Cependant, pour d'autres valeurs, vous devez utiliser memset() ou loop;

exemple: tableau int[10]; memset(tableau,-1, 10 * sizeof(int));

1
répondu Hannah Zhang 2015-07-29 01:21:32

coupant à travers tout le bavardage, la réponse courte est que si vous activez l'optimisation au moment de la compilation, vous ne ferez pas mieux que cela:

int i,value=5,array[1000]; 
for(i=0;i<1000;i++) array[i]=value; 

bonus ajouté: le code est en fait lisible :)

1
répondu JWDN 2016-11-05 16:12:23
#include<stdio.h>
int main(){
int i,a[50];
for (i=0;i<50;i++){
    a[i]=5;// set value 5 to all the array index
}
for (i=0;i<50;i++)
printf("%d\n",a[i]);
   return 0;
}

il donnera l'o / p 5 5 5 5 5 5 ...... jusqu'à la taille de l'ensemble du tableau

0
répondu Dadhich Sourav 2017-10-26 09:05:14

je sais que l'utilisateur Tarski a répondu à cette question d'une manière similaire, mais j'ai ajouté quelques détails. Je suis un peu rouillé car je suis plus enclin à vouloir UTILISER C++, mais c'est parti.


si vous connaissez la taille du tableau à l'avance...

#include <stdio.h>

typedef const unsigned int cUINT;
typedef unsigned int UINT;

cUINT size = 10;
cUINT initVal = 5;

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal );
void printArray( UINT* myArray ); 

int main() {        
    UINT myArray[size]; 
    /* Not initialized during declaration but can be
    initialized using a function for the appropriate TYPE*/
    arrayInitializer( myArray, size, initVal );

    printArray( myArray );

    return 0;
}

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal ) {
    for ( UINT n = 0; n < size; n++ ) {
        myArray[n] = initVal;
    }
}

void printArray( UINT* myArray ) {
    printf( "myArray = { " );
    for ( UINT n = 0; n < size; n++ ) {
        printf( "%u", myArray[n] );

        if ( n < size-1 )
            printf( ", " );
    }
    printf( " }\n" );
}

il y a quelques mises en garde ci-dessus; l'une est que UINT myArray[size]; n'est pas directement initialisé sur la déclaration, cependant le très le prochain appel de bloc de code ou de fonction initialise chaque élément du tableau à la même valeur que vous voulez. L'autre mise en garde est, vous devrez écrire un initializing function pour chaque type que vous supporterez et vous devrez aussi modifier la fonction printArray() pour supporter ces types.


vous pouvez essayer ce code avec un complier en ligne trouvé ici .

0
répondu Francis Cugler 2018-01-28 19:46:56

Je ne vois aucune exigence dans la question, de sorte que la solution doit être générique: initialisation d'un ensemble éventuellement multidimensionnel non spécifié construit à partir d'éléments éventuellement de structure non spécifiés avec une valeur initiale de membre:

#include <string.h> 

void array_init( void *start, size_t element_size, size_t elements, void *initval ){
  memcpy(        start,              initval, element_size              );
  memcpy( (char*)start+element_size, start,   element_size*(elements-1) );
}

// testing
#include <stdio.h> 

struct s {
  int a;
  char b;
} array[2][3], init;

int main(){
  init = (struct s){.a = 3, .b = 'x'};
  array_init( array, sizeof(array[0][0]), 2*3, &init );

  for( int i=0; i<2; i++ )
    for( int j=0; j<3; j++ )
      printf("array[%i][%i].a = %i .b = '%c'\n",i,j,array[i][j].a,array[i][j].b);
}

résultat:

array[0][0].a = 3 .b = 'x'
array[0][1].a = 3 .b = 'x'
array[0][2].a = 3 .b = 'x'
array[1][0].a = 3 .b = 'x'
array[1][1].a = 3 .b = 'x'
array[1][2].a = 3 .b = 'x'

EDIT: start+element_size changé en (char*)start+element_size

-1
répondu sambowry 2009-10-14 11:12:00