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

Tengo una gran variedad en C (¿No estás registrado como C + + si eso hace una diferencia). Quiero inicializar todos los miembros del mismo valor.

Podría jurar que una vez conocí una forma sencilla 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?

preguntado Oct 14 '08, 11:10

Ninguna de las respuestas hasta ahora menciona la notación de inicializador 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 quita los puntos suspensivos , esos fragmentos se compilan en C99 o C11. -

En realidad, la respuesta de abelenky está usando un inicializador designado, pero no es un código de inicialización completamente formado:

memset () puede ayudar, pero depende del valor. -

memset() discusión específica: stackoverflow.com/questions/7202411/… Creo que solo funciona para 0. -

24 Respuestas

A menos que ese valor sea 0 (en cuyo caso puede omitir alguna parte del inicializador y los elementos correspondientes se inicializarán en 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 perdidos 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 es No 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 significa necesariamente "todos-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 un valor nulo, etc.)

contestado el 23 de mayo de 17 a las 12:05

Al leer el estándar C ++, también puede hacer int array [10] = {}; para inicializar a cero. Sin embargo, no tengo el estándar C para verificar que esto también sea válido. - trabajomad3

En 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

C99 tiene muchas características interesantes para la inicialización de estructuras y arreglos; la única característica que no tiene (pero que tenía Fortran IV, 1966) es una forma de repetir un inicializador particular para una matriz. - jonathan leffler

@CetinSert: ¿Qué quieres decir con que no funciona? Hace exactamente lo que dice esta respuesta que debería hacer. No hace lo que dice el comentario en su código, pero ese comentario es incorrecto. - benjamin lindley

@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 esta afirmación. - benjamin lindley

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

Respondido 13 Oct 09, 23:10

Y esa sintaxis provoca un gran aumento en el tamaño del archivo de los binarios compilados. Para N = 65536 (en lugar de 1024), ¡mi tamaño binario salta de 15 KB a 270 KB! - sert de cetina

@CetinSert El compilador tiene que agregar 65536 ints en datos estáticos, que son 256 K, exactamente el aumento de tamaño que ha observado. - qrdl

@CetinSert ¿Por qué debería hacerlo? Es un comportamiento estándar del compilador, no específico para los inicializadores designados. Si inicializa estáticamente 65536 ints, como int foo1 = 1, foo2 = 1, ..., foo65536 =1; obtendrá el mismo aumento de tamaño. - qrdl

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

@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

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 realizar 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 macros son negociables.

contestado el 23 de mayo de 17 a las 12:05

Solo consideraría esto en casos extremos, seguramente un memset es la forma más elegante de expresarlo. - u0b34a0f6ae

Si los datos deben ser compatibles con ROM, no se puede utilizar memset. - Profesor Falken

El preprocesador generará realmente el código a partir de #defines. Con dimensiones de matriz más grandes, el tamaño del ejecutable aumentará. Pero definitivamente + por la idea;) - Leonid

@Alcott, en computadoras viejas y aún en muchos sistemas embebidos, el código finalmente se coloca en un EPROM or ROM. ROM-able también ha llegado a significar, en sistemas embebidos, "código puesto en flash", porque tiene aproximadamente las mismas implicaciones, es decir, que la memoria no se puede escribir en tiempo de ejecución. Es decir, no se puede utilizar memset o cualquier otra instrucción para actualizar o cambiar la memoria. Sin embargo, las constantes se pueden expresar y actualizar o editar en ROM antes de que se inicie el programa. - Profesor Falken

@ u0b34a0f6ae: Tenga en cuenta que también puede utilizar este método si VAL_1X no es un solo entero sino una lista. Como afirma Amigable, este es también el camino a seguir para los sistemas integrados en los que desea definir los valores de inicio de una memoria EEPROM o Flash. En ambos casos no puede usar memset(). - Martín Scharrer

Si desea asegurarse de que todos los miembros de la matriz se inicialicen 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 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.

Respondido 14 Oct 08, 19:10

es esto correcto ? int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} }; - Praveen Gowda IV

No. Está omitiendo la dimensión más interna, que no está permitida. Esto dará un error del compilador. - franco szczerba

Tanto los inicializadores como la inferencia de longitud se introdujeron en C99. - Dedo

@Palec: No, la inferencia de longitud ha estado en C desde los días de C preestándar (desde que se publicó la primera edición de K&R, y probablemente un tiempo antes). Los inicializadores designados eran nuevos en C1, pero esto no usa inicializadores designados. - jonathan leffler

Vi un código que usaba esta sintaxis:

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

Donde se vuelve particularmente útil es si está creando una matriz que usa 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 escribe algunos de los valores de enumeración fuera de orden.

Se puede encontrar más sobre esta técnica. aquí y aquí.

respondido 22 mar '12, 18:03

Esta es la sintaxis del inicializador C99, ya cubierta por algunas de las otras respuestas. Sería útil hacer la declaración en char const *array[] = { ... }; o incluso char const * const array[] = { ... };¿No podrías? - jonathan leffler

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.

Respondido 14 Oct 08, 14:10

Para que conste, es básicamente una versión más lenta y detallada de memset(myArray, VALUE, ARRAY_SIZE); - Benson

¿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 bytes. - Matt

@Benson: no puede reemplazar el código anterior con memset en plataformas donde sizeof (int)> sizeof (char). Intentalo. - cristianwue

Puede hacer todo el proceso del 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 agudiza, si no agrega los inicializadores adicionales apropiados, obtiene basura).

memset le da un tiempo de ejecución para hacer el trabajo, pero ningún tamaño de código bien hecho es inmune a los cambios de tamaño de 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 lo haría parte del proceso de compilación.

Respondido 14 Oct 08, 14:10

¿Podría agregar algún ejemplo sobre el uso de memset para inicializar la matriz? - Sopalajo de Arriérez

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.

Respondido 27 ago 10, 09:08

Para inicializar tipos de datos 'normales' (como matrices int), puede usar la notación de corchetes, pero pondrá a cero los valores después del último 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};

Respondido 14 Oct 08, 14:10

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

array = initial_value

en su idioma favorito con capacidad para arreglos (el mío es Fortran, pero hay muchos otros) y vincularlo a su código C. Probablemente desee resumirlo para que sea una función externa.

Respondido 27 ago 10, 09:08

Si la matriz es 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 moviendo el índice.

Respondido 25 Oct 08, 13:10

Existe 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 la parte que se ha configurado en la parte que no se ha configurado, duplicando el tamaño con cada siguiente operación de copia

Para 1 000 000 elementos int array 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;
}

Respondido 03 Oct 15, 12:10

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 dos veces más rápido que el loopfill. - RS1980

Al igual que con cualquier código de evaluación comparativa, debe tener mucho cuidado. 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í, ejecutándose en una MacBook Pro con macOS Sierra 10.12.3 y usando GCC 6.3.0, que la primera vez, usando el bucle tarda alrededor de 4600 µs, mientras que el memfill() el código tarda alrededor de 1200 µs. Sin embargo, en iteraciones posteriores, el bucle tarda entre 900 y 1000 µs mientras que el memfill() el código tarda 1000-1300 µs. La primera iteración probablemente se vea afectada por el tiempo para llenar el caché. Invierta las pruebas y memfill() es lento la primera vez. - jonathan leffler

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

Si su compilador admite expresiones de doblez, puedes usar la magia de plantilla y std::index_sequence para generar una lista de inicializadores con el valor que desee. Y puedes incluso constexpr y siéntete 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 a la código en el trabajo (en Wandbox)

Respondido 13 Feb 19, 10:02

  1. Si su matriz se declara como estática o es global, todos los elementos de la matriz ya tienen el valor predeterminado predeterminado 0.
  2. Algunos compiladores establecen el valor predeterminado de la matriz en 0 en el 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 * tamaño de (int));

Respondido 29 Jul 15, 02:07

Nadie ha mencionado el orden de í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

Respondido 22 Feb 16, 07:02

<iostream> no es válido C as std::cout, std::cin, etc. es parte del std::namespace y C no es compatible namespaces. Intenta usar <stdio.h> por printf(...) en lugar de. - francisco cugler

int matriz [1024] = {[0 ... 1023] = 5}; Como lo anterior funciona bien, pero asegúrese de que no haya espacios entre los ... puntos

Respondido el 10 de enero de 21 a las 11:01

Utilice el formato al publicar el código: stackoverflow.com/editing-help - Cassandra S.

Estaba confundido por int myArray[10] = { 0 }. Pensé que podría aplicarse a cualquier otra constante. Pero no fue así. Tu solución ayuda. - Codexplorer

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; 

Bono adicional: el código es realmente legible :)

respondido 05 nov., 16:16

La pregunta solicitó específicamente la inicialización. Esto no es explícitamente inicialización, sino asignación realizada. después de inicialización. Puede que se haga de inmediato, pero aún no es la inicialización. - Andy

Completamente no útil 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 sean parte de la pregunta original, manténgalo simple. Dicho esto, @Community probablemente lo logró. - JWDN

Conozco a ese usuario Tarski Respondí esta pregunta de manera similar, pero agregué algunos detalles más. Perdona algo de mi C porque estoy un poco oxidado porque estoy más inclinado a querer usar C ++, pero aquí va.


Si conoce el tamaño de la matriz de antemano ...

#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 ese UINT myArray[size]; no se inicializa directamente tras la declaración, sin embargo, el siguiente bloque de código o llamada a función inicializa cada elemento de la matriz con el mismo valor que desea. La otra salvedad es que tendrías que escribir una initializing function para cada type apoyará y también tendrá que modificar el printArray() función para apoyar esos tipos.


Puede probar este código con un compilador en línea encontrado aquí.

Respondido el 28 de enero de 18 a las 19:01

Para la inicialización retrasada (es decir, la 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;

Respondido 19 Oct 18, 18:10

Si el tamaño de la matriz se conoce de antemano, se podría usar una macro C_ARRAY_INITIALIZE del preprocesador Boost para hacer el trabajo sucio por usted:

#include <boost/preprocessor/repetition/enum.hpp>
#define C_ARRAY_ELEMENT(z, index, name) name[index]
#define C_ARRAY_EXPAND(name,size) BOOST_PP_ENUM(size,C_ARRAY_ELEMENT,name)
#define C_ARRAY_VALUE(z, index, value) value
#define C_ARRAY_INITIALIZE(value,size) BOOST_PP_ENUM(size,C_ARRAY_VALUE,value)

Respondido el 08 de Septiembre de 20 a las 09:09

#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á el o / p 5 5 5 5 5 5 ...... hasta el tamaño de toda la matriz

Respondido 26 Oct 17, 10:10

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'

EDIT: start+element_size cambiado a (char*)start+element_size

Respondido 14 Oct 09, 12:10

Tengo dudas de si esto es una solución o no. No estoy seguro de si sizeof(void) incluso es válido. - chris lutz

No funciona. Solo se inicializan los dos primeros, el resto no se inicializan. 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 memcpy() se superpone 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

En el pasado (y no digo que sea una buena idea), establecí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.

Respondido el 14 de enero de 19 a las 08:01

Eso no funcionará de manera confiable. En mi humilde opinión, el estándar debería haber proporcionado funciones que eran como memcpy pero especificó el orden de copia de abajo hacia arriba o de arriba hacia abajo en caso de superposición, pero no es así. - Super gato

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 funciones indocumentadas. Si bien es más eficiente copiar la memoria hacia adelante, no hay nada en la especificación que diga 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 otro https://www.youtube.com/watch?v=xB-eutXNUMXJtA&feature=youtu.be - y defectuoso. Utilizando memmove() no lo hace funcionar. - jonathan leffler

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, podrías hacerlo en un bucle 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 realizar 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 mediante:

*(array + index)

Etc.

Respondido 16 Oct 19, 23:10

El operador de coma garantiza nominalmente la evaluación de izquierda a derecha. Si no hay efectos secundarios en las expresiones, entonces puede ser posible paralelizar las operaciones, pero sería inusual que un compilador lo hiciera. - jonathan leffler

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.