Alguém tem uma maneira de inicializar uma matriz de int
s (qualquer tipo de multi-byte é muito bem), para um valor diferente de zero e não -1 simplesmente? Por que eu quero dizer, existe uma maneira de fazer isso de uma só vez, sem ter que fazer 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
Apenas FYI, usando memset()
desta forma em arrays estáticos fornece:
arr[0] = 0x01010101 arr[1] = 0x01010101 arr[2] = 0x01010101
A outra opção:
for(count = 0; count < 30; count++) arr[count] = 1; // Yup, that does it, but it's two lines.
Alguém tem outras ideias? Contanto que seja código C, não há limites na solução. (outras libs estão bem)
Esta é uma extensão do GCC:
int a[100] = {[0 ... 99] = 1};
for (count = 0; count < 30; count++) arr[count] = 1;
Uma linha. 🙂
Você disse algo sobre 2 linhas, mas você pode fazê-lo em uma linha usando vírgula ,
operador.
for(count = 0; count < 30 ; arr[count] = 1,count++);
A única maneira sensata de fazer isso durante a boot (em vez de tempo de execução) parece ser:
#define ONE1 1 #define FIVE1 ONE1, ONE1, ONE1, ONE1, ONE1 #define TEN1 FIVE1, FIVE1 #define TWENTY1 TEN1, TEN1 #define FIFTY1 TWENTY1, TWENTY1, TEN1 #define HUNDRED1 FIFTY1, FIFTY1 int array [100][4] = { HUNDRED1, HUNDRED1, HUNDRED1, HUNDRED1 };
E depois, #define ONE2 2
e assim por diante. Você entendeu a ideia.
EDIT: A razão por que eu escrevi tantas macros foi demonstrar como esta solução é flexível. Para este caso em particular, você não precisa de todos eles. Mas com macros como estas você pode escrever qualquer tipo de lista de inicializadores de uma maneira rápida e flexível:
{ 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 };
Em C, você normalmente desenvolve sua própria “biblioteca de suporte” com 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)
e depois usá-los no seu código como
int arr[30]; SET_ALL_A(arr, 1);
Uma linha com pointers!
for (int *p = a; p < (a + 30); p++) *p = 1;
Ou se você tiver medo prematuro de impacto no desempenho causado pelo cálculo repetido (a + 30)
:
for (int *p = a + 30 - 1; p >= a; p--) *p = 1;
Para a boot de um valor estático, geralmente considero que a digitação seja preferencial, como em:
int arr[30] = {1, 1, 1, 1, ...};
Nesse caso, o compilador pode (e normalmente) cuspir a boot otimizada no código de preâmbulo.
Às vezes, a boot é mais dinâmica, como neste exemplo:
int arr[30]; int x = fetchSomeValue(); for(int i=0; i<30; i++) arr[i] = x;
Nestes casos você tem que codificar e a regra geral é maximizar a legibilidade, não minimizar a digitação. Este código será escrito uma vez e lido várias vezes.