Não escrevo C há muito tempo e, portanto, não tenho certeza de como devo fazer esse tipo de coisa recursiva ... Gostaria que cada célula contivesse outra célula, mas recebo um erro ao longo do tempo. linhas de "campo 'filho' tem tipo incompleto". E aí?
typedef struct Cell {
int isParent;
Cell child;
} Cell;
Respostas:
Claramente, uma célula não pode conter outra célula, pois se torna uma recursão sem fim.
No entanto, uma célula pode conter um ponteiro para outra célula.
fonte
Cell
ainda não está no escopo.Cell*
acell->child
.struct
s em C basicamente apenas armazena todos os seus valores próximos um do outro, seria impossível armazenar uma estrutura em si mesma (porque essa estrutura precisaria conter outra e assim por diante, levando a uma estrutura de memória de tamanho infinito) .struct Cell
, consulte esta resposta .Em C, você não pode fazer referência ao typedef que está criando dentro da própria estrutura. Você precisa usar o nome da estrutura, como no seguinte programa de teste:
Embora seja provavelmente muito mais complicado do que isso no padrão, você pode pensar nisso como o compilador que conhece
struct Cell
a primeira linha da,typedef
mas não a conhecetCell
até a última linha :-) É assim que me lembro dessa regra.fonte
Do ponto de vista teórico, os idiomas podem suportar apenas estruturas auto-referenciais e não auto-inclusivas.
fonte
Existe uma maneira de contornar isso:
Se você o declarar assim, informa corretamente ao compilador que struct Cell e plain-ol'-cell são iguais. Então você pode usar o Cell como normalmente. Ainda temos que usar struct Cell dentro da própria declaração inicial.
fonte
struct Cell;
novo?struct Cell
.struct Cell;
redundante. Se, no entanto, por algum motivo você colocar as duas últimas linhas em um arquivo de cabeçalho que você incluir antes de definir aCell
estrutura com as primeiras quatro linhas, em seguida, o adicionalstruct Cell;
é nececairy.typedef struct Cell Cell;
e ele criaCell
um apelido parastruct Cell
. Não importa se o compilador já viustruct Cell { .... }
antes.Sei que este post é antigo, no entanto, para obter o efeito que você está procurando, tente o seguinte:
Em qualquer um dos dois casos mencionados no fragmento de código acima, você DEVE declarar a estrutura da célula filho como ponteiro. Caso contrário, você receberá o erro "campo 'filho' tem tipo incompleto". O motivo é que "struct Cell" deve ser definido para que o compilador saiba quanto espaço alocar quando é usado.
Se você tentar usar "struct Cell" dentro da definição de "struct Cell", o compilador ainda não poderá saber quanto espaço "struct Cell" deve ocupar. No entanto, o compilador já sabe quanto espaço um ponteiro ocupa e (com a declaração forward) sabe que "Cell" é um tipo de "struct Cell" (embora ainda não saiba o tamanho de uma "struct Cell") ) Portanto, o compilador pode definir uma "célula *" dentro da estrutura que está sendo definida.
fonte
Vamos passar pela definição básica de typedef. O typedef usa para definir um alias para um tipo de dados existente, seja ele definido pelo usuário ou embutido.
por exemplo
A confusão aqui é com a estrutura auto-referencial, devido a um membro do mesmo tipo de dados que não é definido anteriormente. Então, da maneira padrão, você pode escrever seu código como: -
Mas a última opção aumenta algumas linhas e palavras extras com o que normalmente não queremos (somos tão preguiçosos que você sabe;)). Então, prefira a View 2.
fonte
typedef
sintaxe está incorreta (considere, por exemplotypedef int (*foo)(void);
). Seus exemplos de exibição 1 e exibição 2 não funcionam: eles são dostruct Cell
tipo incompleto; portanto, você não pode usá-lochild
no seu código.Outro método conveniente é pré-digitar a estrutura com, tag de estrutura como:
fonte
Uma estrutura que contém uma referência a si mesma. Uma ocorrência comum disso em uma estrutura que descreve um nó para uma lista de links. Cada nó precisa de uma referência para o próximo nó da cadeia.
fonte
Todas as respostas anteriores são ótimas, apenas pensei em fornecer uma visão sobre por que uma estrutura não pode conter uma instância de seu próprio tipo (não uma referência).
é muito importante observar que as estruturas são do tipo "valor", ou seja, elas contêm o valor real; portanto, quando você declara uma estrutura, o compilador deve decidir quanta memória alocará uma instância dela, para que ela percorra todos os seus membros e inclua sua memória para descobrir toda a memória da estrutura, mas se o compilador encontrou uma instância da mesma estrutura dentro, isso é um paradoxo (ou seja, para saber quanta memória a estrutura A leva, você precisa decidir quanta memória struct A leva!).
Mas os tipos de referência são diferentes, se uma estrutura 'A' contém uma 'referência' a uma instância de seu próprio tipo, embora ainda não sabemos quanta memória é alocada para ela, sabemos quanta memória é alocada para uma memória endereço (ou seja, a referência).
HTH
fonte