struct: definicao de um valor da struct A baseado no valor da struct B

3 views
Skip to first unread message

augustowebd

unread,
Nov 21, 2009, 8:56:54 AM11/21/09
to ccppbrasil
salve a todos,

pessoa estou fazendo um curso na ETB e num dos exec surgiu uma dor de
cabeca no seguinte código ( http://www.paste-it.net/public/hf6c251/ ),
ao tentar executar ele dah a seguinte mensagem:
"22 C:\deposito\struct\escola.c `lab' undeclared here (not in a
function) "

ele reclama de que lab nao tah declarado, boa, mas a minha intencao
seria:
1º - cadastrar Labaratorio
2º - cadastrar Professor
3º - Professor Turma

porem, em turma, o valor da capacidade de alunos por turma sera
definida de acordo a capacidade do laboratorio, previamente
cadastrada.
__Aluno alunos[lab->capacidade];


mas num ta dando certo, espero que tenham entendido minha duvida.

grato a todos.

Eric Chiesse

unread,
Nov 22, 2009, 11:59:57 AM11/22/09
to ccppb...@googlegroups.com
Fala cara,

teu errro (pelo menos o q eu pude ver) tá na linha 22. Vc só pode inicializar um array com um inteiro literal ou uma constante inteira. Além disso repare que lab->capacidade ainda não é conhecido, então daria errado mesmo que fosse possível usar variáveis.

Sugestões:
    - Se for c++ opte por usar classes.
    - Se for c++ vc resolve isso fácil usando vector<T>
    - Se for c declare um ponteiro e aloque dinamicamente (crie funções para fazer isso).

Abraço.

Eric.

2009/11/21 augustowebd <augus...@gmail.com>

augustowebd

unread,
Nov 22, 2009, 2:41:25 PM11/22/09
to ccppb...@googlegroups.com
Fala Eric,
vamos comecar agradecendo pela atencao...

2009/11/22 Eric Chiesse <echi...@gmail.com>:
> Fala cara,
>
> teu errro (pelo menos o q eu pude ver) tá na linha 22. Vc só pode
> inicializar um array com um inteiro literal ou uma constante inteira. Além
> disso repare que lab->capacidade ainda não é conhecido, então daria errado
> mesmo que fosse possível usar variáveis.
embora eu tenha de concordar com vc eu gostaria de ressaltar um ponto:
embora eu nao conheca o conteudo o 'lab' turma soh podera existir
apois eu informar lab para ela(para turma) o que faz 'lab' ser
conhecida por turma.

>
> Sugestões:
>     - Se for c++ opte por usar classes.
>     - Se for c++ vc resolve isso fácil usando vector<T>
>     - Se for c declare um ponteiro e aloque dinamicamente (crie funções para
> fazer isso).
bem ai reside o problema, sou modesta parte, muito bom em PHP mas em C
nem tanto, embora tenha muita leitura, ou seja teoria, tenho pouca
pratica, estou fazendo um curso realmente basico e nao sei como fazer
isso, se nao for pedir demais um exemplo ficaria imensamente grato.
sei que isso pra todos deve ser muito basico, mas realmento estou
iniciando em C e gostaria muito de aprender isso para ir vencendo as
duvidas aos poucos.

mais uma vez muito obrigado.

>
> Abraço.
>
> Eric.
>
> 2009/11/21 augustowebd <augus...@gmail.com>
>>
>> salve a todos,
>>
>> pessoa estou fazendo um curso na ETB e num dos exec surgiu uma dor de
>> cabeca no seguinte código ( http://www.paste-it.net/public/hf6c251/ ),
>> ao tentar executar ele dah a seguinte mensagem:
>> "22 C:\deposito\struct\escola.c `lab' undeclared here (not in a
>> function) "
>>
>> ele reclama de que lab nao tah declarado, boa, mas a minha intencao
>> seria:
>> 1º - cadastrar Labaratorio
>> 2º - cadastrar Professor
>> 3º - Professor Turma
>>
>> porem, em turma, o valor da capacidade de alunos por turma sera
>> definida de acordo a capacidade do laboratorio, previamente
>> cadastrada.
>> __Aluno alunos[lab->capacidade];
>>
>>
>> mas num ta dando certo, espero que tenham entendido minha duvida.
>>
>> grato a todos.
>>
>>
>>
>
>
> >
>



--
[Ps: Com a falta do que fazer destes desocupados, imorais, digo
imortais, da ABL(academia brasileira de letras) queira me desculpar
caso haja alguns acentos indevidos.]

...vão-se os objetos, ficam-se as referências, passa o System.gc () e
leva tudo...
PHP5 ZCE::ZEND004231 | $zendPHPCertified->getCandidateById(
http://www.zend.com/zce.php?c=ZEND004231&r=220244122 );
Fale sobre PHP::PHP-Brasília - Comunidade de usuários PHP do DF

Michel Henrique Aquino Santos

unread,
Nov 23, 2009, 6:48:30 AM11/23/09
to ccppb...@googlegroups.com
não sei se o errro é esse, mas olha isso:
 __Aluno alunos[lab->capacidade];

não existe o struct 'lab', e sim o struct:

typedef struct Labaratorio{
char sala[5];
int capacidade;
}__Laboratorio;

acho que é isso.


2009/11/22 augustowebd <augus...@gmail.com>



--
Michel Henrique Aquino Santos
Bacharelado em Ciência da Computação
Universidade Federal de Lavras - UFLA
Linux User # 496756

Fabio A Mazzarino

unread,
Nov 23, 2009, 6:56:29 AM11/23/09
to ccppb...@googlegroups.com
Peguei a conversa pela metade.

Mas o papo é o seguinte.

Oq vc quer fazer precisa ser feito com alocação dinâmica.

__Aluno alunos[lab->capacidade];

É uma alocação estática, e é resolvida em tempo de compilação. Porém
em tempo de compilação lab->capacidade ainda não existe ou não está
acessível (depende de algumas situações).

O ideal é fazer assim, usando alocação estática:

#define LAB_CAPACIDADE 100
__Aluno alunos[LAB_CAPACIDADE]

Ou usando alocação dinâmica:

__Aluno *alunos = NULL;

alunos = new __Aluno[lab->capacidade];

Ou melhor ainda, usando STL, reduz a entropia do código, e diminui as
chances de bugs e leaks:

std::list alunos<__Aluno>;

Fabio




--
Doses Diárias - Achados de um Programador na Internet
http://dosesdiarias.seucaminho.com



2009/11/23 Michel Henrique Aquino Santos <miche...@gmail.com>:

Marcio Gil

unread,
Nov 23, 2009, 8:20:50 AM11/23/09
to ccppb...@googlegroups.com
> -----Original Message-----
> From: augustowebd
> >
> > Sugestões:
> >     - Se for c++ opte por usar classes.
> >     - Se for c++ vc resolve isso fácil usando vector<T>
> >     - Se for c declare um ponteiro e aloque dinamicamente
> > (crie funções para
> > fazer isso).
> bem ai reside o problema, sou modesta parte, muito bom em PHP mas
em C
> nem tanto, embora tenha muita leitura, ou seja teoria, tenho pouca
> pratica, estou fazendo um curso realmente basico e nao sei como
fazer
> isso, se nao for pedir demais um exemplo ficaria imensamente
grato.
> sei que isso pra todos deve ser muito basico, mas realmento estou
> iniciando em C e gostaria muito de aprender isso para ir vencendo
as
> duvidas aos poucos.
>

O que ele quis dizer foi, da maneira mais simples, aproximadamente
isto:

(...)
typedef struct Turma{
struct Labaratorio *lab;
__Aluno *alunos;
}__Turma;

void criar_turma( __Turma *turma, __Laboratorio *lab )
{
turma->lab = lab;
turma->alunos = (__Aluno*)malloc( sizeof(__Aluno) *
lab->capacidade );
}

void liberar_turma( __Turma *turma )
{
free( turma->alunos );
turma->alunos = NULL;
}

int main(int argc, char *argv[])
{
__Laboratorio lab;
__Turma turma;

lab.capacidade = 10;
criar_turma( &turma, &lab );

system( "PAUSE > null " );

liberar_turma( &turma );
return 0;
}


Eric Chiesse

unread,
Nov 23, 2009, 8:39:43 AM11/23/09
to ccppb...@googlegroups.com
Valeu márcio, tava sem tempo pra escrever mas vc traduziu bem.

Um único comentário: Se fizer sentido (só se fizer sentido) eu entregaria a guarda de lab para turma e liberaria a memória de lab tb em liberar_turma.

Mas isso depende da modelagem dele.

Augusto, este é o exemplo q vc pediu.

Abraço.

Eric.

2009/11/23 Marcio Gil <marci...@bol.com.br>

augustowebd

unread,
Nov 23, 2009, 8:54:07 AM11/23/09
to ccppb...@googlegroups.com
Galera vou testar aqui, mas o mestre ae mandando tenho certeza de q
vai funfar tranquilo.
Mais uma vez obrigado ae pelo tempo a mim desprendido e espero fazer o
mesmo pelos, assim como eu agora, futuros iniciantes muito em breve!
PS.: Já sou fã de C e ainda com uma comunidade dessas ae pronto!!!

2009/11/23 Eric Chiesse <echi...@gmail.com>:

Rafael Soares

unread,
Nov 23, 2009, 11:29:19 AM11/23/09
to ccppb...@googlegroups.com
Augusto,

Pode ter certeza que aqui só tem cara fera. As vezes eu fico lendo os assuntos e nem sei do que se tratam.

O mais importante ao meu ver no seu caso, que eu já estava de olho desde o primeiro e-mail é o seguinte, pros iniciantes em C/C++ como eu é importante saber que existe uma diferença entre C e C++.

Uma das coisas mais discutidas é que muitos programadores de C++ ainda programam com a mentalidade de C, no caso se você quer escrever em C++ foque mais na OO e uso da STL, senão o exemplo de código que foi postado é um bom começo.

Eu no caso conheço C bem e sou fraco ainda em C++, mas percebo que quando vou mexer com classes fico preso nos conceitos da programação estruturada, mudando apenas a sintaxe. Por isso pulei pro C# pra fortalecer meus conhecimentos de OO e depois voltar pra C++.

Abraço e boa sorte,

Rafael.

-----Mensagem original-----
De: ccppb...@googlegroups.com [mailto:ccppb...@googlegroups.com] Em nome de augustowebd
Enviada em: segunda-feira, 23 de novembro de 2009 11:54
Para: ccppb...@googlegroups.com
Assunto: [ccppbrasil] Re: struct: definicao de um valor da struct A baseado no valor da struct B
Nenhum vírus encontrado nessa mensagem recebida.
Verificado por AVG - www.avgbrasil.com.br
Versão: 9.0.709 / Banco de dados de vírus: 270.14.78/2521 - Data de Lançamento: 11/23/09 05:52:00

Andre Fernandes

unread,
Nov 23, 2009, 11:55:42 AM11/23/09
to ccppb...@googlegroups.com
Reforçando o que foi dito, programação orientada a objetos exige uma mudança na forma de pensar de quem usa programação estruturada. C++ tem ambos, mas o ideal ao programar em C++ é usar OO realmente.
E isso de usar uma linguagem OO sem usar OO realmente é muito comum, muito mais de que possas imaginar. Até mesmo o pessoal fanático por Java já deve ter visto muita gente programando assim. Contudo isso é um vício e um mal uso da linguagem OO.

PS: programação estruturada não é ruim, pelo contrário, há quem defenda-a perante POO. Mas isso não vem ao caso. O importante é que se uma linguagem tem OO, use o melhor que te for possível, vale a pena.

Abraços,

--
André de Camargo Fernandes


Felipe Magno de Almeida

unread,
Nov 23, 2009, 11:58:27 AM11/23/09
to ccppb...@googlegroups.com
2009/11/21 augustowebd <augus...@gmail.com>:
>
> salve a todos,
>

[snip]

> __Aluno alunos[lab->capacidade];

O uso de identificadores com dois underscores é undefined behavior.
Assim como o uso de um underscore seguido de letra maiuscula.
Se você quiser impedir name clashes, use namespaces em C++ ou em C use
um prefixo que faça sentido pro seu módulo/projeto/companhia, etc.

[snip]

--
Felipe Magno de Almeida

Felipe Magno de Almeida

unread,
Nov 23, 2009, 11:59:53 AM11/23/09
to ccppb...@googlegroups.com
2009/11/23 Andre Fernandes <fernand...@gmail.com>:

> Reforçando o que foi dito, programação orientada a objetos exige uma mudança
> na forma de pensar de quem usa programação estruturada. C++ tem ambos, mas o
> ideal ao programar em C++ é usar OO realmente.

O ideal de C++ é usar o paradigma que mais se encaixa no problema corrente.
E em C++ *geralmente* não é OO. Mas sim programação genérica.
O maior exemplo é a própria STL.

Thiago Adams

unread,
Nov 23, 2009, 12:10:33 PM11/23/09
to ccppbrasil
8

> > Reforçando o que foi dito, programação orientada a objetos exige uma mudança
> > na forma de pensar de quem usa programação estruturada. C++ tem ambos, mas o
> > ideal ao programar em C++ é usar OO realmente.
>
> O ideal de C++ é usar o paradigma que mais se encaixa no problema corrente.
> E em C++ *geralmente* não é OO. Mas sim programação genérica.
> O maior exemplo é a própria STL.

C++ não é apenas uma linguagem OO.
O ideal é usar vários paradigmas e podem ser ao mesmo tempo.

Já vi programadores vindos do C# e Java levarem anos para perderem "o
vício" assim como alguns nunca perderm o vício do C.
A minha sugestão é aprender C++ com C++ através de exemplos de livros
modernos e atualizados.

augustowebd

unread,
Nov 23, 2009, 11:57:18 AM11/23/09
to ccppb...@googlegroups.com
salve Rafael,
sem querer enxer a thread e o saco da galera,
eu sei um pouco de OO, rsss, jah de C++ nem tanto pois sei que ela eh
umas das unicas(senao unica) que aceita heranca multipla, o que me
colocaria no banco dos estudantes novamente pra rever este conceito de
heranca multiplas se muda algo, mas por agora estou focando apenas em
C ANSI puro mesmo.

Meu proposito eh trabalhar com driver, desenvolver extensao pra o PHP,
linguagem que me considero programador, e futramente trabalhar na area
de seguranca.

2009/11/23 Rafael Soares <rafae...@gmail.com>:

augustowebd

unread,
Nov 23, 2009, 12:07:28 PM11/23/09
to ccppb...@googlegroups.com
fala Marcio/galera

[snip]


> typedef struct Turma{
>  struct Labaratorio *lab;
>  __Aluno *alunos;
> }__Turma;
>
> void criar_turma( __Turma *turma, __Laboratorio *lab )
> {
>  turma->lab = lab;
>  turma->alunos = (__Aluno*)malloc( sizeof(__Aluno) *
> lab->capacidade );
> }
>
> void liberar_turma( __Turma *turma )
> {
>  free( turma->alunos );
>  turma->alunos = NULL;
> }

[snip]

esta forma seria o que encontraria em uma empresa, ou seja, eh uma
forma profissinal de resolver este problema?
ou esta eh uma forma de resolver o problema?

grato.

Ronaldo

unread,
Nov 23, 2009, 12:20:36 PM11/23/09
to ccppbrasil
Olá, Felipe.

Você fez confusão com uma recomendação do X3J11 sobre os espaços de
nomes reservados para a biblioteca STDC. Segundo o comitê de
padronização da linguagem, identificadores que se iniciam com o
caractere sublinhado e uma letra maiúscula ou outro sublinhado estão
sempre reservados para qualquer uso, dentro do escopo de definição da
biblioteca STDC. Essa não é uma regra da linguagem C, mas uma
convenção adotada pelo comitê X3J11 visando evitar colisões de espaços
de nomes, visto que a linguagem C tem um espaço de nomes muito sujo.

Sugere-se que um usuário da bibliteca STDC não utilize nomes iniciando
com sublinhados acompanhados por um caractere maiúsculo ou outro
sublinhado, justamente para evitar-se colisões de nomes com a
implementação da biblioteca STDC em uso na sua unidade de tradução.
Caso discorde dessa minha observação, sugiro a leitura do livro "A
Biblioteca Standard C" de autoria de P.J. Plauger, ISBN 85-7001-902-5,
capítulo de apresentação, sexta página. Inclusive sugiro este livro
para todos os programadores que querem tirar o melhor proveito da
biblioteca STDC, pois trata-se de uma excelente publicação sobre o
assunto.

O erro que você apontou:

__Aluno alunos[lab->capacidade];

não tem nada a ver com o nome do tipo de dados do vetor, mas com a
declaração do vetor em si. C não suporta a declaração de estruturas de
dados dinâmicas, sendo necessário dizer ao compilador o tamanho do
vetor. O fato de C não suportar a declaração de estruturas de dados
dinâmicas, como os vetores PHP ou os dicionários de Python, não
significa dizer que a linguagem não suporta estruturas dinâmicas.
Bastaria alterar a declaração acima para algo como:

__Aluno * alunos;

As rotinas que mantém essa estrutura de dados ficam responsáveis pelo
controle de alocação/desalocação do vetor dinâmico implementado
através de um apontador.

Espero ter ajudado.

On 23 nov, 14:58, Felipe Magno de Almeida <felipe.m.alme...@gmail.com>
wrote:
> 2009/11/21 augustowebd <augustow...@gmail.com>:

Felipe Magno de Almeida

unread,
Nov 23, 2009, 12:32:58 PM11/23/09
to ccppb...@googlegroups.com
2009/11/23 Ronaldo <ronaldo.f...@gmail.com>:

>
> Olá, Felipe.
>
> Você fez confusão com uma recomendação do X3J11 sobre os espaços de
> nomes reservados para a biblioteca STDC.

Não estou confundindo. Não tenho certeza sobre C, mas em C++ a
utilização destes identificadores resulta em undefined behavior.
Quanto estiver em casa vou procurar no meu padrão.

Ronaldo

unread,
Nov 23, 2009, 12:34:03 PM11/23/09
to ccppbrasil
Olá, Augusto.

Não existe uma forma "profissional" de resolver um problema. Um
problema é resolvido ou não é. O seu código é uma solução otimista
para o problema. E é justamente no otimismo da sua solução que reside
sua maior falha. Assumir que os ponteiros que você recebe são válidos
é uma suposição que considero válida. Grande parte da biblioteca STDC
parte dessa suposição, pois não é possível verificar se um ponteiro é
válido a não ser que você desenvolva um alocador de memória que
verifique as arenas de memória alocada, coisa que malloc, realloc,
calloc e free não o fazem por definição da biblioteca.

Bem, o otimismo está na alocação de recursos dentro da função
"criar_turma". Você acredita que o sistema irá lhe devolver uma arena
válida de memória, mas isso pode não ser verdade em situações de carga
excessiva. É interessante acrescentar um tratamento de erro para
verificar se a sua estrutura foi inicializada satisfatoriamente.

Tratamento de erros é um assunto complexo e cada um tem uma visão de
como resolver o problema. Para uma função tão básica quanto essa,
sugiro que você devolva ao chamador um código indicando o erro que
ocorreu ou zero no caso de sucesso, um dialeto comum nas funções de
biblioteca. Evite de cuspir mensagens em funções que não tem interface
com o usuário.

Espero ter ajudado.

Ronaldo Faria Lima

unread,
Nov 23, 2009, 12:47:40 PM11/23/09
to ccppb...@googlegroups.com
Vou lhe poupar o trabalho:

"2 In addition, identifiers containing a double underscore (__) or begin-
ning with an underscore and an upper-case letter are reserved for use
by C++ implementations and standard libraries and shall not be used
otherwise; no diagnostic is required."

Fonte: http://www.open-std.org/jtc1/sc22/open/n2356/lex.html#lex.name

É isso o que diz o padrão C++ 1997 publicado pelo X3J16. Basicamente
segue a mesma linha de raciocínio do padrão STDC. O que é interessante
observar é que alguns compiladores podem gerar warnings ou até mesmo
erros para justamente forçarem a adoção das sugestões do padrão.
Apesar de ter um espaço de nomes muito mais limpo que C, a colisão de
nomes ainda é possível e essa sugestão visa justamente evitar-se isso.

A despeito da discussão sobre padrões ou não, Felipe, eu sou de
opinião que nomes iniciados com sublinhados devem ser evitados,
justamente para evitar colisões de espaços de nomes. Em alguns casos a
colisão passa em branco pelo compilador e acaba resultando na
linkedição de um programa que tem comportamento totalmente aleatório,
como eu já presenciei no passado.

Abraços!

Ronaldo

2009/11/23 Felipe Magno de Almeida <felipe.m...@gmail.com>:

Marcio Gil

unread,
Nov 23, 2009, 1:40:41 PM11/23/09
to ccppb...@googlegroups.com
> -----Original Message-----
> From: augustowebd
>
> esta forma seria o que encontraria em uma empresa, ou seja, é uma
> forma Professional de resolver este problema?
> ou esta é uma forma de resolver o problema?
>

Isto depende do padrão adotado pela empresa. A solução que sugeri é
uma das formas mais simples de fazer o que você quer utilizando a
linguagem C padrão ANSI.

Mas quando você for fazer algo mais profissional (numa empresa ou em
um projeto acadêmico), provavelmente você utilizará C++ com classes
e STL, ou, se ANSI C for um requisito, você deverá utilizar
estruturas de dados com alocação dinâmica.

O exemplo que você deu é um típico problema de processamento de
dados, então é provável que você precise armazenar, restaurar e
processar os dados em um arquivo. Então uma versão mais completa
seria utilizando apenas alocação dinâmica, sem estruturas sendo
alocadas na pilha:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
char matricula[10];
char nome[60];
int idade;
float peso;
} Aluno;

typedef struct {
char nome[60];
char disciplinas[50];
} Professor;

typedef struct {


char sala[5];
int capacidade;

} Laboratorio;

typedef struct {
Laboratorio *lab;
Aluno *alunos;
} Turma;

void criar_turma( Turma **turma, Laboratorio *lab )
{
*turma = (Turma*)malloc( sizeof(Turma) );
(*turma)->lab = lab;
(*turma)->alunos = (Aluno*)malloc( sizeof(Aluno) * lab->capacidade
);
}

void liberar_turma( Turma **turma )
{
free( (*turma)->alunos );
free( *turma );
*turma = NULL;
}

void criar_lab( Laboratorio **lab )
{
/* Deixo como um exercício para o leitor */
}

void liberar_lab( Laboratorio **lab )
{
/* Deixo como um exercício para o leitor */
}

void criar_aluno( Aluno **aluno )
{
/* Deixo como um exercício para o leitor */
}

void liberar_aluno( Aluno **aluno )
{
/* Deixo como um exercício para o leitor */
}

void criar_professor( Professor **prof )
{
/* Deixo como um exercício para o leitor */
}

void liberar_professor( Professor **prof )
{
/* Deixo como um exercício para o leitor */
}

int main(int argc, char *argv[])
{

Laboratorio *lab;
Turma *turma;

criar_lab( &lab );


lab.capacidade = 10;
criar_turma( &turma, &lab );

system( "PAUSE > NUL" );

liberar_turma( &turma );
liberar_lab( &turma );

return 0;
}

Marcio Gil

unread,
Nov 23, 2009, 1:46:28 PM11/23/09
to ccppb...@googlegroups.com
Errata:

aqui deveria ser:

criar_turma( &turma, lab );

>
> system( "PAUSE > NUL" );
>
> liberar_turma( &turma );
> liberar_lab( &turma );

e aqui:

liberar_lab( &lab );

>
> return 0;
> }
>
>

Reply all
Reply to author
Forward
0 new messages