Jak zainicjować wszystkie elementy tablicy do tej samej wartości?

Mam dużą tablicę w C (nie C++, jeśli to robi różnicę). Chcę zainicjować wszystkie Członkowie do tej samej wartości. Mógłbym przysiąc, że kiedyś znałem prosty sposób na to. Mógłbym użyć memset() w moim przypadku, ale czy nie ma na to sposobu, który jest wbudowany w składnię C?

Author: Lundin, 2008-10-14

18 answers

Chyba że ta wartość to 0 (W takim przypadku można pominąć jakąś część inicjalizatora i odpowiednie elementy zostaną zainicjowane na 0), nie ma łatwego sposobu.

Nie przeocz jednak oczywistego rozwiązania:

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

Elementy z brakującymi wartościami zostaną zainicjalizowane na 0:

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

Więc to zainicjalizuje wszystkie elementy na 0:

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

W C++, pusta lista inicjalizacyjna również zainicjalizuje każdy element na 0. Jest to niedozwolone z C:

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

Pamiętaj, że obiekty o statycznym czasie przechowywania zostaną zainicjowane na 0, jeśli nie inicjalizator jest określony:

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

I że " 0 "niekoniecznie oznacza" wszystkie-bity-zero" , więc użycie powyższego lepsze i bardziej przenośne niż memset (). (Wartości zmiennoprzecinkowe będą inicjalizowana na +0, Wskaźniki na wartość null, itd.)

 1056
Author: aib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:24

Jeśli twoim kompilatorem jest GCC możesz użyć następującej składni:

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

Zobacz szczegółowy opis: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html

 352
Author: qrdl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-13 22:43:06

Do statycznej inicjalizacji dużej tablicy o tej samej wartości, bez wielokrotnego kopiowania i wklejania, można użyć makr:

#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 };

Jeśli chcesz zmienić wartość, musisz dokonać wymiany tylko w jednym miejscu.

Edit: possible useful extensions

(dzięki uprzejmości Jonathan Leffler )

Można łatwo uogólnić za pomocą:

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

Wariant można utworzyć używając:

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

Który współpracuje ze strukturami lub związkami tablice.

#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) };

Nazwy makr są negocjowalne.

 163
Author: mouviciel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:36

Jeśli chcesz mieć pewność, że każdy element tablicy jest jawnie zainicjalizowany, po prostu pomiń wymiar z deklaracji:

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

Kompilator wydedukuje wymiar z listy inicjalizatora. Niestety, dla tablic wielowymiarowych można pominąć tylko Wymiar zewnętrzny:

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

Jest OK, ale

int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
Nie jest.
 59
Author: Frank Szczerba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-14 18:30:25

Widziałem jakiś kod, który używał tej składni:

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

Gdzie staje się szczególnie przydatna, to jeśli tworzysz tablicę, która używa enums jako indeksu:

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

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

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

To utrzymuje porządek, nawet jeśli zdarza się, że niektóre wartości enum są niezgodne z porządkiem.

Więcej o tej technice można znaleźć tutaji tutaj.

 45
Author: abelenky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-22 18:34:31
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

Myślę, że to jest lepsze niż

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

Przy zmianie rozmiaru tablicy.

 22
Author: Tarski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-14 13:34:02

Możesz zrobić całą statyczną inicjalizację, jak opisano powyżej, ale może to być prawdziwa wpadka, gdy zmieni się rozmiar tablicy (gdy tablica się embiggens, jeśli nie dodasz odpowiednich dodatkowych inicjalizatorów, otrzymasz śmieci).

Memset daje Runtime hit do wykonywania pracy, ale żaden rozmiar kodu wykonany prawidłowo nie jest odporny na zmiany rozmiaru tablicy. Zastosowałbym To rozwiązanie prawie we wszystkich przypadkach, gdy tablica była większa niż, powiedzmy, kilkadziesiąt elementów.

Gdyby to było naprawdę ważne że tablica została zadeklarowana statycznie, napiszę program, który napisze program dla mnie i uczyni go częścią procesu budowania.

 11
Author: plinth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-14 13:29:25

Oto inny sposób:

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},
};

Zobacz:

C-Rozszerzenia

]}

Następnie zadaj pytanie: Kiedy można używać rozszerzeń C?

Powyższy przykład kodu znajduje się w systemie wbudowanym i nigdy nie ujrzy światła z innego kompilatora.

 8
Author: humble_guru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-27 08:04:06

Do inicjalizacji 'normalnych' typów danych (jak tablice int), można użyć notacji nawiasowej, ale zeruje ona wartości po ostatnim, jeśli w tablicy jest jeszcze miejsce:

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};
 5
Author: warren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-14 13:17:39

Lekko języczkowa odpowiedź; Napisz wypowiedź

array = initial_value

W Twoim ulubionym języku obsługującym tablice (moim jest Fortran, ale jest wiele innych) i połącz go z kodem C. Pewnie chciałbyś ją zapakować, żeby była funkcją zewnętrzną.

 5
Author: High Performance Mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-27 08:06:18

Jeśli tablica jest int lub cokolwiek o rozmiarze int lub twój rozmiar mem-pattern pasuje dokładnie razy do int (tj. wszystkie zera lub 0xA5A5A5A5), najlepszym sposobem jest użycie memset () .

W Przeciwnym Razie wywołaj memcpy () w pętli przesuwającej indeks.

 4
Author: ddimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-25 12:43:00

Istnieje szybki sposób inicjalizacji tablicy dowolnego typu o podanej wartości. Działa bardzo dobrze z dużymi tablicami. Algorytm jest następujący:

  • zainicjalizuj pierwszy element tablicy (zwykły sposób)
  • Kopiuj część, która została ustawiona na część, która nie została ustawiona, podwajając Rozmiar przy każdej kolejnej operacji kopiowania

Dla 1 000 000 elementów int tablica jest 4 razy szybsza od zwykłej inicjalizacji pętli (i5, 2 rdzenie, 2.3 GHz, Pamięć 4gib, 64 bitów):

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
Author: Maciej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-03 11:59:20

Nikt nie wspomniał o kolejności indeksów dostępu do elementów inicjalizowanej tablicy. Mój przykładowy kod Da do niego przykład ilustracyjny.

#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;
}

Wyjście To:

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
Author: hkBattousai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-22 07:58:43
  1. jeśli tablica jest zadeklarowana jako statyczna lub globalna, wszystkie elementy w tablicy ma już domyślną wartość domyślną 0.
  2. Niektóre Kompilatory ustawiają domyślną wartość array na 0 w trybie debugowania.
  3. można łatwo ustawić domyślną wartość na 0 : int array[10] = {0};
  4. jednak dla innych wartości należy użyć memset () lub loop;

Przykład: int array [10]; memset(array,-1, 10 * sizeof (int));

 1
Author: Hannah Zhang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-29 01:21:32

Przecinając wszystkie rozmowy, krótka odpowiedź jest taka, że jeśli włączysz optymalizację w czasie kompilacji, nie zrobisz nic lepszego niż to:

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

Dodany bonus: kod jest faktycznie czytelny:)

 1
Author: JWDN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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;
}

Da o / p 5 5 5 5 ...... do rozmiaru całej tablicy

 0
Author: Dadhich Sourav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 09:05:14

Wiem, że użytkownik Tarski odpowiedział na to pytanie w podobny sposób, ale dodałem jeszcze kilka szczegółów. Wybacz trochę mojego C, ponieważ jestem trochę zardzewiały, ponieważ jestem bardziej skłonny do używania C++, ale proszę bardzo.


Jeśli znasz rozmiar tablicy z wyprzedzeniem...

#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" );
}

Istnieje kilka zastrzeżeń powyżej; jednym z nich jest to, że {[2] } nie jest bezpośrednio inicjowana po deklaracji, jednak następne wywołanie bloku kodu lub funkcji inicjalizuje każdy element tablicy do taką samą wartość, jaką chcesz. Inne zastrzeżenie jest takie, że musisz napisać initializing function dla każdego type, który będziesz obsługiwał, a także zmodyfikować funkcję printArray(), aby obsługiwać te typy.


Możesz wypróbować ten kod z internetowym kompilatorem znalezionym tutaj .

 0
Author: Francis Cugler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-28 19:46:56

Nie widzę żadnych wymagań w pytaniu, więc rozwiązanie musi być ogólne: inicjalizacja nieokreślonej potencjalnie wielowymiarowej tablicy zbudowanej z nieokreślonych możliwych elementów struktury z początkową wartością pręta:

#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);
}

Wynik:

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 changed to (char*)start+element_size

 -1
Author: sambowry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-14 11:12:00