new initialize ejemplos array c arrays initialization array-initialize

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



load array c (19)

  1. Si su matriz se declara como estática o es global, todos los elementos de la matriz ya tienen un 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, tiene que usar memset () o loop;

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

Tengo una gran variedad en C (no C ++ si eso hace una diferencia). Quiero inicializar todos los miembros al 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 hacerlo que esté incorporada en la sintaxis de C?


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 perdidos se inicializarán a 0:

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

Así que 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 duración de almacenamiento estático se inicializarán a 0 si no se especifica un inicializador:

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

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


Aquí hay otra manera:

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:

C-Extensions

En sus designados

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

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


Cortar a través de 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 :)


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 primer elemento de la matriz (forma habitual)
  • copie la parte que se ha establecido en la parte que no se ha configurado, duplicando el tamaño con cada operación de copia siguiente

Para 1 000 000 elementos int array, es 4 veces más rápido que la inicialización de bucle regular (i5, 2 núcleos, 2,3 GHz, memoria de 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; }


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

La salida 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


No veo requisitos en la pregunta, por lo que la solución debe ser genérica: la inicialización de una matriz multidimensional posiblemente 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


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.

Edición: posibles extensiones útiles.

(Cortesía de Jonathan Leffler )

Puedes 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 macro son negociables


Para inicializar los tipos de datos "normales" (como int arrays), puede usar la notación de corchetes, pero después de los últimos, los valores serán cero si aún hay espacio en la matriz:

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


Para la inicialización diferida (es decir, la inicialización del constructor de miembro 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;


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

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

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


Sé que el usuario Tarski respondió a esta pregunta de manera similar, pero agregué algunos detalles más. Perdone 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 antes de tiempo ...

#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 en 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ía que escribir una initializing function para cada type que soportará y también tendría que modificar la función printArray() para admitir esos tipos.

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


Si desea asegurarse de que todos los miembros de la matriz estén inicializados 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} };

esta bien, pero

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

no es.


Si la matriz es int o algo con el tamaño de int o el tamaño de su patrón de mem se ajusta a los 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.



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

array = initial_value

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


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.

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


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

Le dará la o / p 5 5 5 5 5 5 ...... hasta el tamaño de la matriz completa


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 el tamaño de la matriz cambie.