Tenho um array de códigos de cores, cujo tamanho é conhecido em tempo de compilação. Quero declarar outro array do mesmo tamanho. Mas o código abaixo gera um erro.
Posso, é claro, declarar o tamanho como uma constante global e então usar isso na declaração de ambos os arrays. Mas não quero continuar ajustando a constante de tamanho quando adiciono novas cores. Existe uma maneira de fazer isso? (As variáveis são globais.)
static const char *colors[] = {"#0000ff",
"#00ff00",
"#ff0000",
"#ffff00",
"#ff00ff",
"#00ffff",
"#ffffff",
"#000000",
"#ff8040",
"#c0c0c0",
"#808080",
"#804000"};
static const int NUM_COLORS = sizeof(colors) / sizeof(colors[0]);
static ColorButtons color_buttons[NUM_COLORS];
Em C, ao contrário de C++, variáveis com o qualificador
const
não fazem parte de expressões constantes de tempo de compilação. E você não pode definir um array de comprimento variável com duração de armazenamento estático em um escopo de arquivo ou em um escopo de bloco com especificador de classe de armazenamentostatic
.Em vez disso, você poderia escrever, por exemplo
Outra abordagem é a seguinte
embora haja duas vezes em que a expressão é usada
sizeof(colors) / sizeof(colors[0])
.Ou se o seu compilador suporta C23 então
O tamanho de uma matriz de escopo de arquivo, se especificado, deve ser uma expressão constante inteira . Uma variável qualificada com
const
não se qualifica como tal como expressão (isso difere de C++ que permite isso).Em vez de criar
NUM_COLORS
uma variável, crie um símbolo de pré-processador:A expressão para a qual isso se expande é uma expressão constante inteira e, portanto, pode ser usada como o tamanho de uma matriz.
A única coisa que você precisa observar é certificar-se de não redefinir
colors
em um escopo menor, onde você também usariaNUM_COLORS
.static const int NUM_COLORS
-const
variáveis não são expressões constantes necessárias como tamanho das matrizes de duração de armazenamento estático.Você precisa criar uma macrodefinição:
Para complementar as respostas anteriores :
Também é reutilizável.
Se você não tiver certeza se seu array tem algum elemento (também conhecido como ponteiro nulo), você pode retornar 0 neste caso:
Apenas para propagar novamente para macros X - esta é uma tarefa perfeita para eles. Tudo o que você precisa fazer é manter uma lista de macros X no topo e então você pode ter literais de string, valores, contagem de itens, tabelas de consulta etc etc tudo em tempo de compilação. Bastante poderoso e sustentável, mas ao custo da legibilidade para aqueles que não estão acostumados a ler código de macro X.
Exemplo:
Saída: