¿Alguien tiene una manera de inicializar una matriz de ints (cualquier tipo de varios bytes está bien realmente), a un valor distinto de cero y distinto de -1 simplemente? Con lo que quiero decir, ¿hay alguna manera de hacer esto en una sola línea, sin tener que hacer cada elemento individualmente?
int arr[30] = {1, 1, 1, 1, ...}; // that works, but takes too long to type
int arr[30] = {1}; // nope, that gives 1, 0, 0, 0, ...
int arr[30];
memset(arr, 1, sizeof(arr)); // That doesn't work correctly for arrays with multi-byte
// types such as int
Solo para tu información, usando memset() de esta manera en arreglos estáticos da:
for(count = 0; count < 30; count++)
arr[count] = 1; // Yup, that does it, but it's two lines.
¿Alguien tiene otras ideas? Mientras sea código C, no hay límites en la solución. (otras librerías están bien)
hay wmemset() para arreglos de caracteres “anchos”
– Marc B.
20 de noviembre de 2012 a las 16:10
¿Otras bibliotecas no requerirían> 1 línea? #include libother
– mcalex
20 de noviembre de 2012 a las 16:12
@MarcB – No está mal … dos problemas menores, primero entiendo wchar_t is compiler-specific and can be as small as 8 bits por lo que podría ser un solo byte. En segundo lugar, esperaba algo que pudiera funcionar en diferentes tipos. Pero no es una mala sugerencia. Gracias.
– Miguel
20 de noviembre de 2012 a las 16:18
Mac OS X tiene memset_pattern4(), memset_pattern8() y memset_pattern16() desde la versión 10.5.
– Pascal Cuoq
20 de noviembre de 2012 a las 16:19
@mcalex – Touché. Ok, ¿qué tal “1 delineador por configuración”, no contaremos #includes o más opciones para gcc
– Miguel
20 de noviembre de 2012 a las 16:19
iabdalkader
Esta es una extensión GCC:
int a[100] = {[0 ... 99] = 1};
Eso es impresionante, no estaba al tanto de la sintaxis. +1
– Miguel
20 noviembre 2012 a las 19:00
Nota para cualquier otra persona que use esto, hay un espacio en blanco entre los dígitos y el ... lo cual es importante
– Miguel
20 de noviembre de 2012 a las 19:04
@Mike verifique el enlace, también puede inicializar múltiples rangos y elementos individuales.
– iabdalkader
20 de noviembre de 2012 a las 19:23
Corríjame si me equivoco, pero los inicializadores designados en el lenguaje C son: typedef struct { int x; int y} type; luego type t = { .x=1, .y=2 }; Nunca he visto la notación .. ni he oído hablar de ella como inicializador designado. Creo que esta es una extensión GCC más allá de los inicializadores designados C estándar.
– Lundin
21 de noviembre de 2012 a las 7:49
@Lundin es una extensión GCC, como mencioné, y se describe en el enlace a continuación Inicializadores designados sección. mi respuesta fue editada, no estoy seguro de cómo se llama, pero creo que tal vez “inicializador de rango” sea más apropiado.
También puede escribir todo su programa en C en una sola línea. Si alguien pudiera proporcionar una razón fundamental sobre cómo eso tiene sentido, me encantaría escucharlo.
– Lundin
21 de noviembre de 2012 a las 12:30
Lundin
La única forma sensata de hacer esto durante la inicialización (en lugar del tiempo de ejecución) parece ser:
Y después, #define ONE2 2 y así. Entiendes la idea.
EDITAR: La razón por la que escribí tantas macros fue para demostrar cuán flexible es esta solución. Para este caso en particular no los necesita todos. Pero con macros como estas puedes escribir cualquier tipo de lista de inicializadores de forma rápida y flexible:
{
FIFTY1, FIFTY2, // 1,1,1,1... 50 times, then 2,2,2,2... 50 times
TWENTY3, EIGHTY4 // 3,3,3,3... 20 times, then 4,4,4,4... 80 times
... // and so on
};
Hormiga
En C, normalmente desarrolla su propia “biblioteca de soporte” con macros como
#define SET_ALL(a_, n_, v_)\
do { size_t i, n = (n_); for (i = 0; i < n; ++i) (a_)[i] = (v_); } while(0)
#define SET_ALL_A(a_, v_) SET_ALL(a_, sizeof(a_) / sizeof *(a_), v_)
#define ZERO_ALL(a_, n_) SET_ALL(a_, n_, 0)
#define ZERO_ALL_A(a_) SET_ALL_A(a_, 0)
y luego utilícelos en su código como
int arr[30];
SET_ALL_A(arr, 1);
Ese es realmente un punto importante, por qué no pensé en incluir solo una macro para encargarme de eso, está más allá de mí…
– Miguel
20 de noviembre de 2012 a las 17:24
Si crea una macro repugnante como esta, ¿por qué no escribir una para realmente inicializar la matriz, en lugar de establecerla en tiempo de ejecución de esta manera? Suponga que “arr” tiene una duración de almacenamiento estática y desea aprovechar las reglas de inicialización especiales para tales variables (se inicializan antes de que se llame a main).
– Lundin
21 de noviembre de 2012 a las 12:27
@Lundin: si tuviera conocimiento de alguna característica de C que me permitiera inicializar la matriz según lo solicitado, la usaría. Pero, por desgracia, no tengo ni idea de cómo hacerlo. Veo la “macro repulsiva” anterior como lo mejor disponible en C. Si puede sugerir algo mejor, soy todo oídos.
– Ant
21 de noviembre de 2012 a las 16:01
Archie
¡Una línea con punteros!
for (int *p = a; p < (a + 30); p++) *p = 1;
o si eres prematuramente miedo al impacto en el rendimiento causado por el cálculo repetido (a + 30):
for (int *p = a + 30 - 1; p >= a; p--) *p = 1;
Ese es realmente un punto importante, por qué no pensé en incluir solo una macro para encargarme de eso, está más allá de mí…
– Miguel
20 de noviembre de 2012 a las 17:24
Si crea una macro repugnante como esta, ¿por qué no escribir una para realmente inicializar la matriz, en lugar de establecerla en tiempo de ejecución de esta manera? Suponga que “arr” tiene una duración de almacenamiento estática y desea aprovechar las reglas de inicialización especiales para tales variables (se inicializan antes de que se llame a main).
– Lundin
21 de noviembre de 2012 a las 12:27
@Lundin: si tuviera conocimiento de alguna característica de C que me permitiera inicializar la matriz según lo solicitado, la usaría. Pero, por desgracia, no tengo ni idea de cómo hacerlo. Veo la “macro repulsiva” anterior como lo mejor disponible en C. Si puede sugerir algo mejor, soy todo oídos.
– Ant
21 de noviembre de 2012 a las 16:01
ConejoCurioso
Para la inicialización a un valor estático, generalmente he considerado escribirlo como preferido, como en:
int arr[30] = {1, 1, 1, 1, ...};
En este caso, el compilador puede (y generalmente lo hace) generar una inicialización optimizada en el código de preámbulo.
A veces la inicialización es más dinámica, como en este ejemplo:
int arr[30];
int x = fetchSomeValue();
for(int i=0; i<30; i++) arr[i] = x;
En estos casos, debe codificarlo y la regla general es maximizar la legibilidad, no minimizar la escritura. Este código se escribirá una vez y se leerá multitud de veces.
¿Ha sido útil esta solución?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información
hay wmemset() para arreglos de caracteres “anchos”
– Marc B.
20 de noviembre de 2012 a las 16:10
¿Otras bibliotecas no requerirían> 1 línea?
#include libother
– mcalex
20 de noviembre de 2012 a las 16:12
@MarcB – No está mal … dos problemas menores, primero entiendo
wchar_t is compiler-specific and can be as small as 8 bits
por lo que podría ser un solo byte. En segundo lugar, esperaba algo que pudiera funcionar en diferentes tipos. Pero no es una mala sugerencia. Gracias.– Miguel
20 de noviembre de 2012 a las 16:18
Mac OS X tiene
memset_pattern4()
,memset_pattern8()
ymemset_pattern16()
desde la versión 10.5.– Pascal Cuoq
20 de noviembre de 2012 a las 16:19
@mcalex – Touché. Ok, ¿qué tal “1 delineador por configuración”, no contaremos
#includes
o más opciones paragcc
– Miguel
20 de noviembre de 2012 a las 16:19