luismsantana Posted August 13, 2012 at 02:01 PM Report Share #472146 Posted August 13, 2012 at 02:01 PM boa tarde ... eu tenho este exercicio (alignea) para fazer: d) Efectue a seguinte alteração na função proposta na alínea anterior. Os alunos a eliminar da lista original devem ser inseridos numa outra lista (a lista vai conter os nós dos alunos com média inferior à média da turma). Esta nova função deve receber como argumento adicional uma referência para o ponteiro para o início da nova lista (i.e., recebe um ponteiro para esse ponteiro). o código da função da aligena c) penso que seja (se tiver feito bem): al elimina(al p, al pal[]) { int alunos=0; float media_geral=0; al aux,anterior=NULL; while(p!=NULL) { alunos++; media_geral+=p->media; p=p->prox; } media_geral=media_geral/alunos; aux=p; while(aux!=NULL) { if(aux->media<media_geral){ anterior->prox=aux->prox; free(aux); } anterior=aux; aux=aux->prox; } return p; } e a estrutura declarada: typedef struct aluno student,*al; struct aluno{ char nome[50]; int notas[5]; float media; al prox; }; alguma dica de como fazer esta alteração? abraço Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 13, 2012 at 02:03 PM Report Share #472148 Posted August 13, 2012 at 02:03 PM uma iteração - por cada iteração - uma comparação - se dentro do parâmetro (inferior à média) - adicionar à segunda lista - remover da lista original IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
pmg Posted August 13, 2012 at 02:07 PM Report Share #472150 Posted August 13, 2012 at 02:07 PM ... se tiver feito bem ... al elimina(al p, al pal[]) { while(p!=NULL) { /* ... */ p=p->prox; } aux=p; while(aux!=NULL) { /* ... */ } /* ... */ } Nope, nao esta bem feito. Repara: no fim do primeiro ciclo p tem NULL; depois metes esse NULL no aux e nunca executas o segundo ciclo. 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! Link to comment Share on other sites More sharing options...
luismsantana Posted August 13, 2012 at 02:11 PM Author Report Share #472151 Posted August 13, 2012 at 02:11 PM uma iteração - por cada iteração - uma comparação - se dentro do parâmetro (inferior à média) - adicionar à segunda lista - remover da lista original sim, essa parte eu percebo e sei como remover ... mas é suposto criar um array de ponteiros, certo? a minha dúvida principal é se crio esse array na main ou na função e depois como manipular para mover da primeira lista para a segunda, utilizando esse array! Repara: no fim do primeiro ciclo p tem NULL; depois metes esse NULL no aux e nunca executas o segundo ciclo. ah pois é, tens razão ... thanks ... mas entao como faço para correr a lista novamente no segundo ciclo? ponho o aux=p logo no inicio? Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 13, 2012 at 02:15 PM Report Share #472153 Posted August 13, 2012 at 02:15 PM minha dúvida principal é se crio esse array na main ou na função Esta nova função deve receber como argumento adicional uma referência para o ponteiro para o início da nova lista IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
luismsantana Posted August 13, 2012 at 02:19 PM Author Report Share #472154 Posted August 13, 2012 at 02:19 PM certo, sorry ja to com a cabeça em água xD mas e em relação à segunda parte da dúvida? Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 13, 2012 at 02:23 PM Report Share #472156 Posted August 13, 2012 at 02:23 PM certo, sorry ja to com a cabeça em água xD mas e em relação à segunda parte da dúvida? não te posso responder sem saber mais sobre a estrutura "al". não faço ideia se é um elemento de uma "lista ligada" ou de uma "lista duplamente ligada" por outras palavras : tens de fazer post da definição do "al" IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
luismsantana Posted August 13, 2012 at 04:46 PM Author Report Share #472175 Posted August 13, 2012 at 04:46 PM e a estrutura declarada: typedef struct aluno student,*al; struct aluno{ char nome[50]; int notas[5]; float media; al prox; }; Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 13, 2012 at 05:14 PM Report Share #472177 Posted August 13, 2012 at 05:14 PM não tens nenhuma função que retre um elemento específico da lista e/ou outra função que adicione ?? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
luismsantana Posted August 13, 2012 at 05:25 PM Author Report Share #472178 Posted August 13, 2012 at 05:25 PM (edited) #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct aluno student,*al; struct aluno{ char nome[50]; int notas[5]; float media; al prox; }; void grava_ficheiro(int n_al, char *nome) { int i,j; student aux; FILE *f; f=fopen(nome,"wb"); i=0; while(i<n_al) { printf("nome do aluno:"); scanf("%s",&aux.nome); printf("\n"); for(j=0;j<5;j++) { printf("nota%d:",j); scanf("%d",&aux.notas[j]); } printf("\n"); fwrite(&aux,sizeof(student),1,f); i++; } fclose(f); } al busca_ficheiro_lista(char *nome1) { int total=0,i,j,total_notas=0,nota,c[20]; float media=0; al p=NULL,novo; student aux,b[20]; FILE *f; f=fopen(nome1,"rb"); while(fread(&aux,sizeof(student),1,f)==1){ novo=(al) malloc(sizeof(student)); strcpy(novo->nome,aux.nome); for(i=0;i<5;i++){ c[i]=aux.notas[i]; nota=c[i]; for(j=0;j<5;j++) novo->notas[i]=nota; } novo->prox=NULL; for(i=0;i<5;i++){ total_notas+=c[i]; } media=(float)total_notas/5; novo->media=media; if(p==NULL) p=novo; else p->prox=novo; } fclose(f); return p; } al elimina(al p, al pal[]) { int alunos=0; float media_geral=0; al aux,anterior=NULL; while(p!=NULL) { alunos++; media_geral+=p->media; p=p->prox; } media_geral=media_geral/alunos; aux=p; while(aux!=NULL) { if(aux->media<media_geral){ anterior->prox=aux->prox; free(aux); } anterior=aux; aux=aux->prox; } return p; } void main() { } está aí o código todo ... ainda nao tenho nada na main porque ainda nao executei, so compilei, e fui fazendo alignea a alignea ... a indentacção do programa não é assim, quando colei aqui ficou assim ... peço desculpa entao desde já por isso! Edited August 13, 2012 at 05:29 PM by pmg Indentacao Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 13, 2012 at 05:34 PM Report Share #472179 Posted August 13, 2012 at 05:34 PM isto vai ser complicado ... achas que chegas lá se te disser só para andares com ponteiros de um lado para o outro ? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
pmg Posted August 13, 2012 at 05:35 PM Report Share #472180 Posted August 13, 2012 at 05:35 PM ainda nao tenho nada na main porque ainda nao executei, so compilei ... Vai executando testes enquanto vais contruindo o programa, funcao a funcao. A compilacao isoladamente nao e suficiente para teres uma base solida. Assim, ao introduzires uma funcao nova, podes usar as funcoes antigas com a certeza que estao bem. 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! Link to comment Share on other sites More sharing options...
luismsantana Posted August 13, 2012 at 05:51 PM Author Report Share #472181 Posted August 13, 2012 at 05:51 PM isto vai ser complicado ... achas que chegas lá se te disser só para andares com ponteiros de um lado para o outro ? gostava de poder dizer que sim, mas nao ainda nao domino esta parte dos arrays de ponteiros :\ Vai executando testes enquanto vais contruindo o programa, funcao a funcao. A compilacao isoladamente nao e suficiente para teres uma base solida. Assim, ao introduzires uma funcao nova, podes usar as funcoes antigas com a certeza que estao bem. obrigado pela dica 😉 isto vai ser complicado ... achas que chegas lá se te disser só para andares com ponteiros de um lado para o outro ? é tipo isto? void transfere(plivro *p1, plivro *p2) { plivro aux; if(*p1 == NULL) return; /*lista L1 vazia*/ aux = *p1; *p1 = aux->prox; aux->prox = *p2; *p2 = aux; } Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 13, 2012 at 06:16 PM Report Share #472184 Posted August 13, 2012 at 06:16 PM estas a ir no bom caminho, apesar de teres imensos problemas no código ... estive a ver o código que apresentaste no primeiro post, acho melhor corrigires esse primeiro. vais ver que depois disso terás melhor ideia do que tens a fazer notas a ver : - porque gravas um registo diretamente no ficheiro, desse modo nunca terás na lista para ser manipulado - a tua função de leitura do ficheiro tem 50% do código desnecessário que não faz nada - cria uma lista no main e tenta apresentar os dados da lista no ecrã IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
luismsantana Posted August 14, 2012 at 01:50 PM Author Report Share #472227 Posted August 14, 2012 at 01:50 PM - a tua função de leitura do ficheiro tem 50% do código desnecessário que não faz nada boa tarde a função como está funciona ... al busca_ficheiro_lista(char *nome1) { int total=0,i,j,total_notas=0,nota,c[20]; float media=0; al p=NULL,novo; student aux,b[20]; FILE *f; f=fopen(nome1,"rb"); while(fread(&aux,sizeof(student),1,f)==1){ novo=(al) malloc(sizeof(student)); strcpy(novo->nome,aux.nome); for(i=0;i<5;i++){ c[i]=aux.notas[i]; nota=c[i]; for(j=0;j<5;j++) novo->notas[i]=nota; } novo->prox=NULL; for(i=0;i<5;i++){ total_notas+=c[i]; } media=(float)total_notas/5; novo->media=media; if(p==NULL) p=novo; else p->prox=novo; } fclose(f); return p; } como faço para fazer retirar o código desnecessário? Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 14, 2012 at 02:00 PM Report Share #472228 Posted August 14, 2012 at 02:00 PM 1º : novo=(al) malloc(sizeof(student)); strcpy(novo->nome,aux.nome); for(i=0;i<5;i++){ c[i]=aux.notas[i]; nota=c[i]; for(j=0;j<5;j++) novo->notas[i]=nota; } novo->prox=NULL; >> novo=(al) malloc(sizeof(student)); memcpy(novo, aux, sizeof(student)); // uma função para copiar tudo de uma estrutura para outra do mesmo tipo novo->prox=NULL; 2º : for(i=0;i<5;i++){ total_notas+=c[i]; } media=(float)total_notas/5; novo->media=media; o cálculo da média deveria ser fora desta função pela simples razão que alterares um único valor de uma nota qualquer, terás de recalcular a média. conclusão, deverias criar uma função que calcule esse valor e chamar-la sempre que necessário (re)calcular a média do aluno void calcular_media(al aluno) { float total_notas; for(i = 0; i < 5; i++) total_notas += aluno->notas[i]; aluno->media = total_notas / 5; } al busca_ficheiro_lista(char *nome1) { // código inicial de leitura do registo ... // calcular a média calcular_media(novo); if(p==NULL) p=novo; else p->prox=novo; } IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
luismsantana Posted August 14, 2012 at 02:11 PM Author Report Share #472237 Posted August 14, 2012 at 02:11 PM memcpy(novo, aux, sizeof(student)); // uma função para copiar tudo de uma estrutura para outra do mesmo tipo memcpy, nao conhecia ... os profs nao ensinam mesmo nada -.- obrigado HappyHippy ... agora outra coisa, antes de entrar na parte de mexer com os ponteiros, podes analisar-me a função de eliminar, por favor? nao percebo porque nao está a dar :s al elimina(al p) { int alunos=0; float media_geral=0; al aux,anterior=NULL; aux=p; while(p!=NULL) { alunos++; media_geral+=p->media; p=p->prox; } media_geral=media_geral/alunos; printf("%f\n",media_geral); while(aux!=NULL) { if(media_geral>aux->media && anterior==NULL) { anterior=aux->prox; free(aux); } else{ if(media_geral>aux->media) { anterior->prox=aux->prox; free(aux); } } printf("chega aqui?\n"); anterior=aux; aux=aux->prox; } return p; } Link to comment Share on other sites More sharing options...
HappyHippyHippo Posted August 14, 2012 at 02:31 PM Report Share #472244 Posted August 14, 2012 at 02:31 PM 1º - novamente o cálculo da média geral é um passo que deverá ser separado numa função à parte double calcular_media_geral(al p) { int alunos = 0; double sum = 0.0; while(p!=NULL) { alunos++; sum += p->media; p = p->prox; } // verificar sempre o numero de elementos nunca tentes fazer a divisão por zero !!! if (alunos == 0) return 0; return sum / alunos; } agora podes ter um código muito mais limpo al elimina_abaixo_media(al p) { al aux = p, anterior=NULL; // calcular a media global double media_global = calcular_media_global(p); while(aux!=NULL) { // recalcular a media do aluno porque não sei se andaste a mexer nas notas dele calcular_media(aux); // filtar à partida pela média if (media_geral > aux->media) { // verificar se é o primeiro da lista if(anterior==NULL) { // dizer que o primeiro da lista é o seguinte p = p->next; // eliminar o registo free(aux); // vamos verificar o novo primeiro da lista aux = p; } else { // remover o elemento da lista anterior->prox = aux->prox; // eliminar o registo free(aux); // vamos processar o seguinte da lista aux = anterior->prox; } } else { // avançar o ponteiro (deixar estar na lista) anterior = aux; aux = aux->next; } } return p; } IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Link to comment Share on other sites More sharing options...
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