Se eu tiver um arquivo source.c com uma estrutura:
struct a {
int i;
struct b {
int j;
}
};
Como essa estrutura pode ser usada em outro arquivo (ou seja func.c
)?
Devo criar um novo arquivo de cabeçalho, declarar a estrutura lá e incluir esse cabeçalho func.c
?
Ou devo definir a estrutura inteira em um arquivo de cabeçalho e incluí-la em source.c
e func.c
? Como a estrutura pode ser declarada extern
em ambos os arquivos?
Eu deveria typedef
? Se sim, como?
struct b
, mas então sua estruturaa
declara um tipo que não é usado (você provavelmente deve definir um nome de membro, talvezk
, após a chave de fechamento interna e antes do ponto e vírgula.Respostas:
se esta estrutura deve ser usada por algum outro arquivo func.c como fazer isso?
Quando um tipo é usado em um arquivo (ou seja, arquivo func.c), ele deve estar visível. A pior maneira de fazer isso é copiar e colar em cada arquivo de origem necessário.
A maneira certa é colocá-lo em um arquivo de cabeçalho e incluí-lo sempre que necessário.
devemos abrir um novo arquivo de cabeçalho e declarar a estrutura lá e incluir esse cabeçalho no func.c?
Esta é a solução que eu mais gosto, porque torna o código altamente modular. Eu codificaria sua estrutura como:
Eu colocaria funções que usam essa estrutura no mesmo cabeçalho (a função que é "semanticamente" parte de sua "interface").
E normalmente, eu poderia nomear o arquivo com o nome da estrutura e usar esse nome novamente para escolher as definições dos protetores de cabeçalho.
Se você precisar declarar uma função usando um ponteiro para a estrutura, não precisará da definição completa da estrutura. Uma declaração de encaminhamento simples como:
Será suficiente, e diminui o acoplamento.
ou podemos definir a estrutura total no arquivo de cabeçalho e incluí-la em source.c e func.c?
Esta é outra maneira, um pouco mais fácil, mas menos modular: alguns códigos que precisam apenas de sua estrutura para funcionar ainda precisam incluir todos os tipos.
Em C ++, isso pode levar a complicações interessantes, mas isso está fora do tópico (sem tag C ++), então não vou entrar em detalhes.
a seguir, como declarar essa estrutura como externa em ambos os arquivos. ?
Não consigo entender o ponto, talvez, mas Greg Hewgill tem uma resposta muito boa em seu post Como declarar uma estrutura em um cabeçalho que deve ser usado por vários arquivos em c? .
devemos digitá-lo então como?
O motivo é que o gerenciamento de C struct pode ser uma dor: você deve declarar a palavra-chave struct em todos os lugares em que ela é usada:
Enquanto um typedef permitirá que você escreva sem a palavra-chave struct.
É importante que você ainda mantenha um nome para a estrutura. Escrevendo:
irá apenas criar uma estrutura anônima com um nome digitado, e você não poderá encaminhá-la. Portanto, mantenha o seguinte formato:
Assim, você será capaz de usar MyStruct em todos os lugares que deseja evitar adicionar a palavra-chave struct e ainda usar MyStructTag quando um typedef não funcionar (ou seja, declaração de encaminhamento)
Editar:
Corrigida a suposição errada sobre a declaração de struct C99, conforme devidamente observado por Jonathan Leffler .
Editar 01/06/2018:
Craig Barnes nos lembra em seu comentário que você não precisa manter nomes separados para o nome de struct "tag" e seu nome "typedef", como fiz acima por uma questão de clareza.
Na verdade, o código acima pode muito bem ser escrito como:
IIRC, isso é realmente o que C ++ faz com sua declaração de struct mais simples, nos bastidores, para mantê-la compatível com C:
De volta ao C, eu vi os dois usos (nomes separados e mesmos nomes) e nenhum tem desvantagens que eu conheça, então usar o mesmo nome torna a leitura mais simples se você não usar "namespaces" separados em C para structs e outros símbolos .
fonte
struct
tag e otypedef
nome. C usa um namespace diferente parastruct
tags, então você pode usarMyStruct
para ambos.Para uma definição de estrutura que deve ser usada em mais de um arquivo de origem, você definitivamente deve colocá-la em um arquivo de cabeçalho. Em seguida, inclua esse arquivo de cabeçalho em qualquer arquivo de origem que precise da estrutura.
A
extern
declaração não é usada para definições de estrutura, mas em vez disso, é usada para declarações de variáveis (ou seja, algum valor de dados com um tipo de estrutura que você definiu). Se você quiser usar a mesma variável em mais de um arquivo de origem, declare-a comoextern
em um arquivo de cabeçalho como:Então, em um arquivo de origem, defina a variável real:
Se você esquecer de fazer isso ou acidentalmente defini-lo em dois arquivos de origem, o vinculador o informará sobre isso.
fonte
GLOBAL
comoextern
ou nada no topo do cabeçalho e, em seguida, declarar as variáveis comoGLOBAL struct a myAValue;
. Da maioria dos arquivos de origem, você organiza a#define GLOBAL extern
versão a ser usada ( declarando as variáveis) e de exatamente um arquivo de origem faz com que o define vazio seja usado para que as variáveis sejam definidas .ah:
pronto, agora você só precisa incluir ah nos arquivos onde deseja usar esta estrutura.
fonte