aalex Posted March 16, 2012 at 02:28 PM Report #444208 Posted March 16, 2012 at 02:28 PM viva, estou com um problema que não estou a conseguir resolver tenho por objectivo manter nos ficheiro .h apenas a definição das funções, tudo o resto nos .c o meu problema é quando defino por exemplo uma estrutura, exemplo: typedef struct s { .... } *ap; se por exemplo tiver uma função que retorna um "ap" em qualquer ficheiro .h isto vai dar erro pois o tipo "ap" ainda não é conhecido já que esta no .c alguém sabe como resolver? 🙂
Flinger Posted March 16, 2012 at 02:32 PM Report #444209 Posted March 16, 2012 at 02:32 PM Pões o typedef no .h (que é incluido pelos outros que precisarem), mas a declaração da estrutura no .c... Isto é: No .h: typedef struct s *ap; e no .c (que tem de incluir o .h): struct s { .... }; PS: Desta forma todos os ficheiros que incluam o .h vão conhecer o tipo ap, mas não podem aceder aos campos. Todas as funções que acedem aos mesmos têm de estar no .c que define a struct. Se precisares de aceder aos campos em funções de outros .c, então tens de pôr toda a declaração no .h.
pmg Posted March 16, 2012 at 02:35 PM Report #444210 Posted March 16, 2012 at 02:35 PM Mantendo a definição da estrutura num .c podes introduzir um "tipo incompleto" no ficheiro .h struct s; // tipo incompleto; podes usar ponteiros para ele struct s *fx(void); Mas o melhor é meteres a definição da estrutura no ficheiro .h. E, já agora, meteres a definição das funções nos ficheiros .c, mantendo apenas os protóptipos das mesmas no ficheiro .h. What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
aalex Posted March 16, 2012 at 04:22 PM Author Report #444246 Posted March 16, 2012 at 04:22 PM obrigado aos dois sim no .h mantenho apenas os protótipos das funções.. não existe uma outra forma de colocar as estruturas no .c sem a necessidade de colocar os "protótipos" no .h?
seuqram Posted March 16, 2012 at 04:29 PM Report #444249 Posted March 16, 2012 at 04:29 PM obrigado aos dois sim no .h mantenho apenas os protótipos das funções.. não existe uma outra forma de colocar as estruturas no .c sem a necessidade de colocar os "protótipos" no .h? acho que n dá!
pmg Posted March 16, 2012 at 04:40 PM Report #444252 Posted March 16, 2012 at 04:40 PM não existe uma outra forma de colocar as estruturas no .c sem a necessidade de colocar os "protótipos" no .h? Uma outra solução seria usares void* nos parametros das funções. Na implementação da função convertes o void* para struct whatever * mais ou menos como se faz para a função de comparação usada no qsort // header file void *fx(void *); // implementation file .c struct foo { /* whetever */ }; void *fx(void *data) { struct foo *value, *parm = data; /* usa parm->membro para atribuir valores a value->membro */ return value; } // usage #include "foo.h" void *opaque = fx(NULL); while (opaque) opaque = fx(opaque); What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
pmg Posted March 16, 2012 at 04:53 PM Report #444254 Posted March 16, 2012 at 04:53 PM Queres fazer uma coisa parecida com o FILE*? Pesquisa por "opaque pointer". A Wikipedia tem um artigo sobre Opaque Pointers ... What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
aalex Posted March 16, 2012 at 05:23 PM Author Report #444260 Posted March 16, 2012 at 05:23 PM obrigado pmg pela ajuda, de facto o void* tinha sido a solução já encontrada, o chato é depois ter de fazer imensos castings vou analisar para tentar encontrar a melhor solução
HappyHippyHippo Posted March 16, 2012 at 05:58 PM Report #444273 Posted March 16, 2012 at 05:58 PM existe alguma razão para não quereres colocar o typedef struct s { .... } *ap; no .h ??? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
pmg Posted March 16, 2012 at 06:18 PM Report #444282 Posted March 16, 2012 at 06:18 PM o chato é depois ter de fazer imensos castings Não, não tens de fazer casting nenhuns se construires o código a pensar nisso. No meu exemplo acima, por exemplo, não há nenhum cast. Em C, o tipo void* é compativel com ponteiros para qualquer tipo de objecto; ou seja o compilador faz as conversões necessárias (se houver) automagicamente e podes aceder ao "tipo base" normalmente. Estás a compilar C++, talvez? #include <stdio.h> #include <stdlib.h> // outro exemplo struct whatever { int data; /* ... */ }; int cmp(const void *a, const void *b) { const struct whatever *aa, *bb; // valores de tipo void * são compativeis com objectos de tipo struct whatever * // por isso as atribuições seguintes são válidas sem cast nenhum (atencão ao const) aa = a; bb = b; return aa->data - bb->data; } int main(void) { struct whatever x[4] = {{7}, {4}, {9}, {2}}; qsort(x, 4, sizeof *x, cmp); if (x->data != 2) puts("Oops"); return 0; } Podes ver que o ideone não se chateia pela ausencia dos casts. Em C, muitos casts são completamente desnecessarios (para não dizer que são um erro) e indicam que o autor do codigo não sabe "falar" C --- ou que esta a tentar escrever codigo fonte para mais que uma linguagem. Onde os casts sao necessarios e nas funcoes declaradas em <ctype.h>, nalguns casos de printf() ("%p"), abuso da linguagem, e pouco mais. Talvez te interesse ler um artigo do Richard Heathfield em que explica porque os casts sao desnecessarios e ate errados. (Nota: o artigo nao se encontra disponivel no endereco original, por isso o link vai para o wayback archive.) What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
Flinger Posted March 16, 2012 at 07:37 PM Report #444288 Posted March 16, 2012 at 07:37 PM existe alguma razão para não quereres colocar o typedef struct s { .... } *ap; no .h ??? Normalmente eu uso isso em API's em que não quero que quem a vai usar saiba o que está na estrutura 🙂 Por isso apenas ponho a typedef no header, e a declaração da struct no .c, tal como disse no meu post. Normalmente para Handlers e coisa e tal... Muitas vezes também os defino como void *, como disse o pmg.
HappyHippyHippo Posted March 16, 2012 at 08:17 PM Report #444291 Posted March 16, 2012 at 08:17 PM Normalmente eu uso isso em API's em que não quero que quem a vai usar saiba o que está na estrutura 🙂 Por isso apenas ponho a typedef no header, e a declaração da struct no .c, tal como disse no meu post. Normalmente para Handlers e coisa e tal... Muitas vezes também os defino como void *, como disse o pmg. então usa os tipos opacos ... não existe necessidade de void * IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
aalex Posted March 17, 2012 at 10:17 PM Author Report #444397 Posted March 17, 2012 at 10:17 PM obrigado a todos pela preciosa ajuda, em especial ao pmg pela dedicação e pelo artigo do Richard depois das dicas e de ler mais uns artigos já consegui resolver tudo como pretendia
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now