Estive olhando c ponteiro para array de structs e tentando aplicá-lo ao meu exemplo.
Cheguei a este trecho de código, que compila bem:
#include <stdio.h>
enum test_e {
eONE,
eTWO,
eTHREE,
};
typedef enum test_e test_t;
#define NUMITEMS 12
extern test_t my_arr[NUMITEMS];
test_t (*my_arr_ptr)[NUMITEMS];
test_t my_arr[NUMITEMS] = { 0 };
int main()
{
my_arr_ptr = &my_arr;
printf("Hello World %p\n", my_arr_ptr);
return 0;
}
No trecho acima, temos uma atribuição de my_arr_ptr
variável ao endereço da my_arr
variável (usando o operador "endereço de ", e comercial &
).
No entanto, o que eu gostaria de fazer é inicializar a my_arr_ptr
variável com o endereço da my_arr
variável - o que eu acho possível, visto que após a linha test_t my_arr[NUMITEMS] = { 0 };
o compilador deve "saber" um endereço e tamanho de my_arr
.
No entanto, se eu tentar isso:
#include <stdio.h>
enum test_e {
eONE,
eTWO,
eTHREE,
};
typedef enum test_e test_t;
#define NUMITEMS 12
extern test_t my_arr[NUMITEMS];
test_t (*my_arr_ptr)[NUMITEMS];
test_t my_arr[NUMITEMS] = { 0 };
my_arr_ptr = &my_arr;
int main()
{
//my_arr_ptr = &my_arr;
printf("Hello World %p\n", my_arr_ptr);
return 0;
}
... isso falha com:
Compilation failed due to following error(s).
main.c:25:1: warning: data definition has no type or storage class
25 | my_arr_ptr = &my_arr;
| ^~~~~~~~~~
main.c:25:1: warning: type defaults to ‘int’ in declaration of ‘my_arr_ptr’ [-Wimplicit-int]
main.c:25:1: error: conflicting types for ‘my_arr_ptr’; have ‘int’
main.c:21:10: note: previous declaration of ‘my_arr_ptr’ with type ‘test_t (*)[12]’ {aka ‘enum test_e (*)[12]’}
21 | test_t (*my_arr_ptr)[NUMITEMS];
| ^~~~~~~~~~
main.c:25:14: warning: initialization of ‘int’ from ‘test_t (*)[12]’ {aka ‘enum test_e (*)[12]’} makes integer from pointer without a cast [-Wint-conversion]
25 | my_arr_ptr = &my_arr;
| ^
main.c:25:14: error: initializer element is not computable at load time
main.c: In function ‘main’:
main.c:30:26: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int’ [-Wformat=]
30 | printf("Hello World %p\n", my_arr_ptr);
| ~^ ~~~~~~~~~~
| | |
| | int
| void *
| %d
Tanto quanto eu posso ver, "aviso: a definição de dados não tem tipo ou classe de armazenamento" ocorre:
porque você não pode executar o código fora das funções
( Por que estou recebendo este erro: "definição de dados não tem tipo ou classe de armazenamento"? )
Então, a obtenção de "endereço de" é considerada "código" em C, então não posso usá-lo fora das funções?
Em caso afirmativo, como posso usar "endereço do" operador "funções externas" no trecho abaixo, que também compila bem?:
#include <stdio.h>
void func_one(void) {
printf("func_one\n");
}
void func_two(void) {
printf("func_two\n");
}
void* funcs_arr[2] = { &func_one, &func_two };
int main()
{
printf("Hello World %p\n", funcs_arr[0]);
return 0;
}
As variáveis globais são inicializadas em sua definição. Apenas faça:
Endereços de objetos globais são expressões constantes e podem ser usados para inicializar outros objetos globais. Veja 6.6p7 :
A definição de "constante de endereço" pode ser encontrada em 6.6p9 :