¿Cómo inicializar todos los miembros de una matriz al mismo valor?

968

Tengo una gran matriz en C (no C ++ si eso hace la diferencia). Quiero inicializar a todos los miembros del mismo valor.

Podría jurar que una vez conocí una manera simple de hacer esto. Podría usar memset()en mi caso, pero ¿no hay una manera de hacer esto que esté integrada en la sintaxis de C?

Mate
fuente
16
Ninguna de las respuestas hasta ahora menciona la notación inicializada designada que es factible con C99 y superior. Por ejemplo: 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 elimina los puntos suspensivos , esos fragmentos se compilan bajo C99 o C11.
Jonathan Leffler
En realidad, la respuesta de abelenky es usar un inicializador designado, pero no está completamente formado código de inicialización
Rob11311
memset () puede ayudar, pero depende del valor.
Nick
2
memset()discusión específica: stackoverflow.com/questions/7202411/… Creo que solo funciona para 0.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

1239

A menos que ese valor sea 0 (en cuyo caso puede omitir alguna parte del inicializador y los elementos correspondientes se inicializarán a 0), no hay una manera fácil.

Sin embargo, no pase por alto la solución obvia:

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

Los elementos con valores faltantes se inicializarán a 0:

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

Entonces esto inicializará todos los elementos a 0:

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

En C ++, una lista de inicialización vacía también inicializará cada elemento a 0. Esto no está permitido con C:

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

Recuerde que los objetos con una duración de almacenamiento estático se inicializarán a 0 si no se especifica ningún inicializador:

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

Y ese "0" no necesariamente significa "todos los bits cero", por lo que usar lo anterior es mejor y más portátil que memset (). (Los valores de coma flotante se inicializarán a +0, los punteros a valor nulo, etc.)

aib
fuente
27
Leyendo el estándar C ++, también puede hacer int array [10] = {}; a cero inicializar. Sin embargo, no tengo el estándar C para verificar que esto también sea válido.
workmad3
54
Mirando la sección 6.7.8 Inicialización del estándar C99, no parece que se permita una lista de inicializadores vacía.
Jonathan Leffler
77
C99 tiene muchas características agradables para la estructura y la inicialización de la matriz; La única característica que no tiene (pero Fortran IV, 1966, tenía) es una forma de repetir un inicializador particular para una matriz.
Jonathan Leffler
8
@CetinSert: ¿Qué quieres decir con que no funciona? Hace exactamente lo que esta respuesta dice que debería hacer. No hace lo que dice el comentario en su código, pero ese comentario es incorrecto.
Benjamin Lindley
99
@CetinSert: Eres el único que afirmó, en ese comentario, que todos los elementos se establecerían en -1. Esta respuesta afirma, con razón, que todos los elementos no especificados se ponen a cero. Los resultados de su código están de acuerdo con este reclamo.
Benjamin Lindley
394

Si su compilador es GCC, puede usar la siguiente sintaxis:

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

Consulte la descripción detallada: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html

qrdl
fuente
12
Y esa sintaxis provoca un gran aumento en el tamaño del archivo de los archivos binarios compilados. ¡Para N = 65536 (en lugar de 1024), mi binario salta de 15 KB a 270 KB de tamaño !!
Cetin Sert
50
@CetinSert Compiler tiene que agregar 65536 ints en datos estáticos, que es 256 K, exactamente el aumento de tamaño que ha observado.
qrdl
15
@CetinSert ¿Por qué debería hacerlo? Es un comportamiento de compilador estándar, no específico para los inicializadores designados. Si inicializa estáticamente 65536 ints, int foo1 = 1, foo2 = 1, ..., foo65536 =1;obtendrá el mismo aumento de tamaño.
qrdl
27
mejor aún: "int array [] = {[0 ... 1023] = 5}", el tamaño de la matriz se establecerá automáticamente en 1024, más fácil y seguro de modificar.
Francois
44
@Francois o para una matriz 2D bool array[][COLS] = { [0...ROWS-1][0...COLS-1] = true}, aunque no estoy seguro de que sea más legible que el formulario completo.
g33kz0r
178

Para inicializar estáticamente una matriz grande con el mismo valor, sin copiar y pegar múltiples, puede usar 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 necesita cambiar el valor, debe hacer el reemplazo en un solo lugar.

Editar: posibles extensiones útiles

(cortesía de Jonathan Leffler )

Puede generalizar esto fácilmente con:

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

Se puede crear una variante usando:

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

que funciona con estructuras o matrices compuestas.

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

Los nombres de las macros son negociables.

Mouviciel
fuente
12
Solo consideraría esto en casos extremos, seguramente un memset es la forma más elegante de expresarlo.
u0b34a0f6ae
47
Si los datos deben ser compatibles con ROM, no se puede usar memset.
contrato del Prof. Falken incumplió el
99
El preprocesador generará el código de #defines. Con dimensiones de matriz más grandes, el tamaño ejecutable crecerá. Pero definitivamente + para la idea;)
Leonid
77
@Alcott, en computadoras antiguas y aún en muchos sistemas integrados, el código finalmente se coloca en una EPROM o ROM . ROM-able también ha llegado a significar, en sistemas integrados, "código puesto en flash", porque tiene las mismas implicaciones, a saber, que la memoria no se puede escribir en tiempo de ejecución. Es decir, memset o cualquier otra instrucción para actualizar o cambiar la memoria no se puede utilizar. Sin embargo, las constantes se pueden expresar y flashear o ROM antes de que comience el programa.
contrato del Prof. Falken incumplió
44
@ u0b34a0f6ae: Tenga en cuenta que también puede usar este método si VAL_1Xno es un número entero sino una lista. Al igual que los estados Amigable, este también es el camino a seguir para los sistemas embebidos en los que desea definir los valores de inicio de una memoria EEPROM o Flash. En ambos casos no puedes usar memset().
Martin Scharrer
63

Si desea asegurarse de que cada miembro de la matriz se inicialice explícitamente, simplemente omita la dimensión de la declaración:

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

El compilador deducirá la dimensión de la lista de inicializadores. Desafortunadamente, para las matrices multidimensionales solo se puede omitir la dimensión más externa:

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

está bien, pero

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

no es.

Frank Szczerba
fuente
es esto correcto ? int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
Praveen Gowda IV
10
No. Estás omitiendo la dimensión más interna, que no está permitida. Esto dará un error de compilación.
Frank Szczerba
44
Tanto los inicializadores como la inferencia de longitud se introdujeron en C99.
Palec
3
@Palec: No, la inferencia de longitud ha estado en C desde los días del C estándar anterior (desde que se publicó K&R 1st Edition, y probablemente un poco antes). Los inicializadores designados eran nuevos en C99, pero esto no está usando inicializadores designados.
Jonathan Leffler
53

Vi un código que usaba esta sintaxis:

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

Donde se vuelve particularmente útil es si está haciendo una matriz que utiliza enumeraciones como índice:

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

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

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

Esto mantiene las cosas en orden, incluso si usted escribe algunos de los valores de enumeración fuera de orden.

Puede encontrar más información sobre esta técnica aquí y aquí .

abelenky
fuente
8
Esta es la sintaxis del inicializador C99, ya cubierta por algunas de las otras respuestas. Podrías hacer la declaración útilmente char const *array[] = { ... };o incluso char const * const array[] = { ... };, ¿no?
Jonathan Leffler
22
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

Creo que esto es mejor que

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

en caso de que cambie el tamaño de la matriz.

Tarski
fuente
12
Para el registro, que es básicamente un más lento, más prolija versión dememset(myArray, VALUE, ARRAY_SIZE);
Benson
18
¿Cómo usaría memset para inicializar una matriz int a un valor mayor que 255? memset solo funciona si la matriz tiene un tamaño de byte.
Matt
21
@Benson: No puede reemplazar el código anterior con memset en plataformas donde sizeof (int)> sizeof (char). Intentalo.
ChrisWue
13

Puede hacer todo lo relacionado con el inicializador estático como se detalla anteriormente, pero puede ser un verdadero fastidio cuando cambia el tamaño de su matriz (cuando su matriz se embebe, si no agrega los inicializadores adicionales apropiados, obtiene basura).

memset le proporciona un tiempo de ejecución correcto para hacer el trabajo, pero ningún resultado de tamaño de código realizado correctamente es inmune a los cambios de tamaño de la matriz. Usaría esta solución en casi todos los casos cuando la matriz fuera más grande que, digamos, unas pocas docenas de elementos.

Si fuera realmente importante que la matriz se declarara estáticamente, escribiría un programa para escribir el programa por mí y hacerlo parte del proceso de compilación.

pedestal
fuente
¿Podría agregar algún ejemplo sobre ese uso memsetpara inicializar la matriz?
Sopalajo de Arrierez
8

Aquí hay otra forma:

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

Ver:

Extensiones C

Inits designados

Luego haga la pregunta: ¿Cuándo se pueden usar extensiones C?

El ejemplo de código anterior está en un sistema integrado y nunca verá la luz de otro compilador.

humilde_guru
fuente
6

Para inicializar los tipos de datos 'normales' (como las matrices int), puede usar la notación de paréntesis, pero pondrá a cero los valores después de la última si todavía hay espacio en la matriz:

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};
madriguera
fuente
5

Si la matriz resulta ser int o algo con el tamaño de int o el tamaño de su patrón de memoria se ajusta a tiempos exactos en un int (es decir, todos los ceros o 0xA5A5A5A5), la mejor manera es usar memset () .

De lo contrario, llame a memcpy () en un bucle que mueve el índice.

ddimitrov
fuente
5

Una respuesta ligeramente irónica; escribe la declaración

array = initial_value

en su lenguaje favorito con capacidad de matriz (el mío es Fortran, pero hay muchos otros), y vincúlelo a su código C. Probablemente quieras envolverlo para que sea una función externa.

Marca de alto rendimiento
fuente
4

Hay una forma rápida de inicializar una matriz de cualquier tipo con un valor dado. Funciona muy bien con matrices grandes. El algoritmo es el siguiente:

  • inicializar el primer elemento de la matriz (forma habitual)
  • copiar parte que se ha configurado en una parte que no se ha configurado, duplicando el tamaño con cada operación de copia siguiente

Para la matriz de 1 000 000elementos int, es 4 veces más rápido que la inicialización de bucle normal (i5, 2 núcleos, 2.3 GHz, memoria 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;
}
Maciej
fuente
2
Lo siento, pero esto no es cierto. Tal vez olvidó activar la optimización de compilación durante sus pruebas (¿probado con el modo de depuración?). Si pruebo esto, el bucle es casi siempre un 50% más rápido que memfill ('siempre' debido a algunas fluctuaciones de carga en mi máquina). Y usando memset (a, 0, sizeof (a)); es incluso el doble de rápido que el loopfill.
RS1980
2
Al igual que con cualquier código de evaluación comparativa, debe ser extremadamente cuidadoso. Agregar un bucle para ejecutar el código de tiempo 10 veces (y duplicar el tamaño de la matriz a 20M) muestra, para mí, correr en un MacBook Pro con macOS Sierra 10.12.3 y usar GCC 6.3.0, que la primera vez, usando el ciclo toma alrededor de 4600 µs, mientras que el memfill()código toma alrededor de 1200 µs. Sin embargo, en las iteraciones posteriores, el ciclo toma alrededor de 900-1000 µs mientras que el memfill()código toma 1000-1300 µs. La primera iteración probablemente se ve afectada por el tiempo para llenar el caché. Invierte las pruebas y memfill()es lento la primera vez.
Jonathan Leffler
2

Nadie ha mencionado el orden del índice para acceder a los elementos de la matriz inicializada. Mi código de ejemplo le dará un ejemplo ilustrativo.

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

El resultado es:

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
hkBattousai
fuente
44
<iostream>No es válido Ccomo std::cout, std::cin, etc. forma parte de la std::namespacey Cno soporta namespaces. Intenta usar <stdio.h>for en su printf(...)lugar.
Francis Cugler
2

Cortando toda la charla, la respuesta corta es que si activa la optimización en tiempo de compilación, no lo hará mejor que esto:

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

Bonificación adicional: el código es realmente legible :)

JWDN
fuente
77
La pregunta solicitó específicamente la inicialización. Esto no es explícitamente la inicialización, sino la asignación realizada después de la inicialización. Puede hacerse de inmediato, pero aún no es la inicialización.
Andy
No es de gran ayuda para una gran tabla de búsqueda estática dentro de una función llamada muchas veces.
Martin Bonner apoya a Monica
... no recuerde que las tablas de búsqueda estáticas dentro de las funciones forman parte de la pregunta original; manténgalo simple. Dicho esto, @Community probablemente lo logró.
JWDN
1
  1. Si su matriz se declara como estática o es global, todos los elementos en la matriz ya tienen el valor predeterminado predeterminado 0.
  2. Algunos compiladores establecen la matriz predeterminada en 0 en modo de depuración.
  3. Es fácil establecer el valor predeterminado en 0: int array [10] = {0};
  4. Sin embargo, para otros valores, debe usar memset () o loop;

ejemplo: int array [10]; memset (matriz, -1, 10 * sizeof (int));

Hannah Zhang
fuente
0
#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;
}

Dará la o / p 5 5 5 5 5 5 ...... hasta el tamaño de toda la matriz

Dadhich Sourav
fuente
0

Sé que el usuario Tarskirespondió a esta pregunta de manera similar, pero agregué algunos detalles más. Perdona parte de mi C porque estoy un poco oxidado porque estoy más inclinado a querer usar C ++, pero aquí está.


Si conoce el tamaño de la matriz con anticipación ...

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

Hay algunas advertencias arriba; uno es que UINT myArray[size];no se inicializa directamente después de la declaración, sin embargo, el siguiente bloque de código o llamada de función inicializa cada elemento de la matriz al mismo valor que desea. La otra advertencia es que tendrías que escribir una initializing functionpara cada una de las typeque admitirás y también deberías modificar la printArray()función para admitir esos tipos.


Puede probar este código con un compilador en línea que se encuentra aquí .

Francis Cugler
fuente
0

Para la inicialización retrasada (es decir, inicialización del constructor de miembros de clase) considere:

int a[4];

unsigned int size = sizeof(a) / sizeof(a[0]);
for (unsigned int i = 0; i < size; i++)
  a[i] = 0;
nikc
fuente
0

Sé que la pregunta original menciona explícitamente C y no C ++, pero si usted (como yo) vino aquí buscando una solución para las matrices de C ++, aquí hay un buen truco:

Si su compilador admite expresiones de plegado , puede usar la plantilla de magia y std::index_sequencegenerar una lista de inicializador con el valor que desee. Y puedes igualarlo constexpry sentirte como un jefe:

#include <array>

/// [3]
/// This functions's only purpose is to ignore the index given as the second
/// template argument and to always produce the value passed in.
template<class T, size_t /*ignored*/>
constexpr T identity_func(const T& value) {
    return value;
}

/// [2]
/// At this point, we have a list of indices that we can unfold
/// into an initializer list using the `identity_func` above.
template<class T, size_t... Indices>
constexpr std::array<T, sizeof...(Indices)>
make_array_of_impl(const T& value, std::index_sequence<Indices...>) {
    return {identity_func<T, Indices>(value)...};
}

/// [1]
/// This is the user-facing function.
/// The template arguments are swapped compared to the order used
/// for std::array, this way we can let the compiler infer the type
/// from the given value but still define it explicitly if we want to.
template<size_t Size, class T>
constexpr std::array<T, Size> 
make_array_of(const T& value) {
    using Indices = std::make_index_sequence<Size>;
    return make_array_of_impl(value, Indices{});
}

// std::array<int, 4>{42, 42, 42, 42}
constexpr auto test_array = make_array_of<4/*, int*/>(42);
static_assert(test_array[0] == 42);
static_assert(test_array[1] == 42);
static_assert(test_array[2] == 42);
static_assert(test_array[3] == 42);
// static_assert(test_array[4] == 42); out of bounds

Puedes echar un vistazo al código en el trabajo (en Wandbox)

Clemens Sielaff
fuente
-1

No veo requisitos en la pregunta, por lo que la solución debe ser genérica: inicialización de una matriz posiblemente multidimensional no especificada construida a partir de elementos de estructura posiblemente no especificados con un valor de miembro inicial:

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

Resultado:

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'

EDITAR: start+element_sizecambiado a(char*)start+element_size

sambowry
fuente
1
Tengo dudas sobre si esta es una solución o no. No estoy seguro de si sizeof(void)es válido.
Chris Lutz
3
No funciona Solo los dos primeros están inicializados, el resto no están inicializados. Estoy usando GCC 4.0 en Mac OS X 10.4.
dreamlax
Esto invoca un comportamiento indefinido porque los datos de origen en el segundo se memcpy()superponen con el espacio de destino. Con una implementación ingenua de memcpy(), puede funcionar, pero no es necesario que el sistema lo haga funcionar.
Jonathan Leffler
-1

En el pasado (y no digo que sea una buena idea), configuraríamos el primer elemento y luego:

memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);

Ni siquiera estoy seguro de que funcionaría más (eso dependería de la implementación de memcpy) pero funciona copiando repetidamente el elemento inicial al siguiente, incluso funciona para matrices de estructuras.

Miguel
fuente
Eso no funcionará de manera confiable. En mi humilde opinión, el estándar debería haber proporcionado funciones que eran similares memcpypero especificadas en orden de copia de arriba a abajo en caso de superposición, pero no lo hace.
supercat
Como dije, fue algo que hicimos que no funcionaría de manera confiable pero, en ese entonces, estábamos más enfocados en la eficiencia que en evitar las funciones indocumentadas. Si bien es más eficiente copiar la memoria hacia adelante, no hay nada en la especificación que indique que no puede copiarla hacia atrás, en un orden aleatorio o dividirla en varios subprocesos. memmove () proporciona la capacidad de copiar sin conflictos.
Mike
Esto es equivalente al código en otra respuesta , y defectuoso. Usar memmove()no lo hace funcionar.
Jonathan Leffler
-2

Si quiere decir en paralelo, creo que el operador de coma cuando se usa junto con una expresión puede hacer eso:

a[1]=1, a[2]=2, ..., a[indexSize]; 

o si te refieres a una sola construcción, puedes hacerlo en un ciclo for:

for(int index = 0, value = 10; index < sizeof(array)/sizeof(array[0]); index++, value--)
  array[index] = index;

// Tenga en cuenta que el operador de coma en una lista de argumentos no es el operador paralelo descrito anteriormente;

Puede inicializar una declinación de matriz:

array[] = {1, 2, 3, 4, 5};

Puede hacer una llamada a malloc / calloc / sbrk / alloca / etc para asignar una región fija de almacenamiento a un objeto:

int *array = malloc(sizeof(int)*numberOfListElements/Indexes);

y acceder a los miembros por:

*(array + index)

Etc.

pchelper4
fuente
El operador de coma nominalmente garantiza la evaluación de izquierda a derecha. Si no hay efectos secundarios en las expresiones, puede ser posible paralelizar las operaciones, pero sería inusual que un compilador lo haga.
Jonathan Leffler