Warning funzione

di il
7 risposte

Warning funzione

Salve,ho realizzato il codice di questo esercizio:
Realizzare una funzione che, dato un elenco di studenti, effettui il calcolo della media dei voti di uno studente cercato per nome o per matricola.
Il tipo di dato studente deve essere rappresentato come un record con 3 campi:
- Nominativo di tipo stringa
- Matricola di tipo intero
- Voti di tipo vettore di interi di dimensione variabile
Quando vado a compilare, ricevo un warning (che ho scritto nel codice) riferito alla funzione char *LeggereNominativoStudente(Studente student) che non mi fa funzionare il programma correttamente in quanto non vengono letti i nominativi degli studenti.
Come posso risolvere ? grazie.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIM 100

typedef char stringa[DIM];

typedef struct {
	int dimensione;
	int *elementi;
}vettore;

typedef struct {
	stringa nominativo;
	int matricola;
	vettore voti;
}Studente;

typedef struct{
	int dimensione;
	Studente *ElencoStudenti;
}VettoreStudenti;

float CalcolareMediaVoti(Studente student);
float SommaVoti(Studente trovato, int dim);
int RicercareStudente(VettoreStudenti elenco, Studente *trovato, Studente studente_cercato, int parametro);
void StampaStudente(Studente student);
void StampaStudenteCercato(Studente student);
void StampareRisultato(int p, float m);
void StampaEsitoNegativo();

//struttura vettore
int LeggereDimensioneVoti(vettore voti);
void ScrivereDimensioneVoti(vettore *voti, int d);
void AllocareMemoriaVoti(vettore *v);
void ScrivereElementoVoti(vettore *voti, int i, int e);
//struttura Studente
int LeggereVotoStudente(vettore voti, int i); // i=posizione voto
void ScrivereVotoStudente(Studente *student, int i, int e); //i=posizione voto, e=voto
void ScrivereDimensioneVotiStudente(Studente *student, int d); //d=dimensione
void ScrivereMatricolaStudente(Studente *student, int mat);
int LeggereMatricolaStudente(Studente student);
void ScrivereNominativoStudente(Studente *student, stringa nome);
char *LeggereNominativoStudente(Studente student);
//struttura VettoreStudenti
int LeggereDimensioneVettoreStudenti(VettoreStudenti elenco);
void ScrivereDimensioneVettoreStudenti(VettoreStudenti *elenco, int d);
void AllocareMemoriaVettoreStudenti(VettoreStudenti *v);
void ScrivereElementoVettoreStudenti(VettoreStudenti *elenco,int i, Studente student);


int main(void){
	VettoreStudenti elenco;
	Studente student_a;
	Studente student_b;
	Studente studente_cercato; //studente che l'utente vuole cercare
	Studente trovato; //struttura dello studente cercato nell'elenco
	int mat; 		//matricola, 6 cifre
	stringa nome;   //nominativo studente
	float media;    //media dei voti dello studente
	int parametro; //parametro di ricerca dello studente: 1 se lo voglio cercare per nome, 2 se per matricola
	int bool = 0; //variabile booleana (0 o 1)

	//assegno dati a student_a
	mat = 716696;
	strcpy(nome, "mario rossi");
	ScrivereMatricolaStudente(&student_a, mat);
	ScrivereNominativoStudente(&student_a, nome);
	ScrivereDimensioneVotiStudente(&student_a, 2);
	ScrivereVotoStudente(&student_a,0,30);
	ScrivereVotoStudente(&student_a,1,20);
	//assegno dati a student_b
	mat = 123456;
	strcpy(nome, "john wick");
	ScrivereMatricolaStudente(&student_b, mat);
	ScrivereNominativoStudente(&student_b, nome);
	ScrivereDimensioneVotiStudente(&student_b, 3);
	ScrivereVotoStudente(&student_b,0,18);
	ScrivereVotoStudente(&student_b,1,20);
	ScrivereVotoStudente(&student_b,2,25);
	//Scrivo la lunghezza del VettoreStudenti elenco
	ScrivereDimensioneVettoreStudenti(&elenco, 2);
	ScrivereElementoVettoreStudenti(&elenco, 0, student_a);
	ScrivereElementoVettoreStudenti(&elenco, 1, student_b);

	//stampo struttura studenti
	StampaStudente(student_a);
	StampaStudente(student_b);

	//cerco uno studente
	strcpy(nome, "john wick");		//cambiare a piacere
	mat = 716696;								//cambiare a piacere
	parametro = 2;                              //cambiare a piacere con 1 o 2
	ScrivereMatricolaStudente(&studente_cercato, mat);
	ScrivereNominativoStudente(&studente_cercato, nome);
	StampaStudenteCercato(studente_cercato);
	bool = RicercareStudente(elenco, &trovato, studente_cercato, parametro);
	if(bool == 1){
		media = CalcolareMediaVoti(trovato);
		StampareRisultato(parametro, media);
	}else StampaEsitoNegativo();

	system("pause");
	return 0;
}

void ScrivereMatricolaStudente(Studente *student, int mat){
	student->matricola = mat;
	return;
}

void ScrivereNominativoStudente(Studente *student, stringa nome){
	strcpy(student->nominativo, nome);
	return;
}

void ScrivereDimensioneVotiStudente(Studente *student, int d){
	ScrivereDimensioneVoti(&student->voti, d); //&student->voti  = indirizzo del campo voti di student
	return;
}

void ScrivereDimensioneVoti(vettore *voti, int d){
	voti->dimensione = d;
	AllocareMemoriaVoti(voti);
	return;
}

void AllocareMemoriaVoti(vettore *v){
	(v->elementi)= (int*) malloc( v->dimensione * sizeof(int));
	return;
}

void ScrivereVotoStudente(Studente *student, int i, int e){
	ScrivereElementoVoti(&student->voti, i, e);
	return;
}

void ScrivereElementoVoti(vettore *voti, int i, int e){
	*(voti->elementi + i) = e;
	return;
}

void ScrivereDimensioneVettoreStudenti(VettoreStudenti *elenco, int dim){
	elenco->dimensione = dim;
	AllocareMemoriaVettoreStudenti(elenco);

}

void AllocareMemoriaVettoreStudenti(VettoreStudenti *v){
	(v->ElencoStudenti) = (Studente*) malloc (v->dimensione * sizeof(int));
}

void ScrivereElementoVettoreStudenti(VettoreStudenti *elenco, int i, Studente student){
	*(elenco->ElencoStudenti + i) = student;
}

void StampaStudente(Studente student){
	printf("\nMatricola> %d", LeggereMatricolaStudente(student));
	printf("\nNominativo> %s", LeggereNominativoStudente(student));
	return;
}

int LeggereMatricolaStudente(Studente student){
	int mat;
	mat = student.matricola;
	return mat;
}

char *LeggereNominativoStudente(Studente student){    
	return student.nominativo;                                 <--------------warning: function returns address of local variable [-Wreturn-local-addr]
}

void StampaStudenteCercato(Studente student){
	printf("\nMatricola> %d", LeggereMatricolaStudente(student));
	printf("\nNominativo> %s", LeggereNominativoStudente(student));
	return;
}

int RicercareStudente(VettoreStudenti elenco, Studente *trovato, Studente studente_cercato, int parametro){
	int i;
	int j = 0;
	int bool = 0;
	i = LeggereDimensioneVettoreStudenti(elenco);
	while(j <= i && bool == 0){
		if (parametro == 1){
			if (LeggereMatricolaStudente(*(elenco.ElencoStudenti + j)) == (studente_cercato.matricola)){
				trovato = (elenco.ElencoStudenti + j);
				bool = 1;
			}
		}else if (parametro == 2){
			if (strcmp(LeggereNominativoStudente(*(elenco.ElencoStudenti + j)), LeggereNominativoStudente(studente_cercato)) == 0){
				trovato = (elenco.ElencoStudenti + j);
				bool = 1;
			}
		}
		j++;
	}
	return bool;
}

int LeggereDimensioneVettoreStudenti(VettoreStudenti elenco){
	int dim;
	dim = elenco.dimensione;
	return dim;
}

float CalcolareMediaVoti(Studente trovato){
	float media;
	int dim;
	int i = 0;
	dim = LeggereDimensioneVoti(trovato.voti);
	if (dim == 0){
		media = -1;
	}
	while(i < dim){
		media = (SommaVoti(trovato, dim)/dim);
	}
	return media;
}

float SommaVoti(Studente trovato, int dim){
	int i = 0;
	float somma = 0;
	while (i < dim){
		somma = (LeggereVotoStudente(trovato.voti, i)) + somma;
		i++;
	}
	return somma;
}

int LeggereVotoStudente(vettore voti, int i){
	int voto;
	voto = *(voti.elementi + i);
	return voto;
}

int LeggereDimensioneVoti(vettore voti){
	int dim;
	dim = voti.dimensione;
	return dim;
}

void StampareRisultato(int parametro, float media){
	if(parametro == 1){
		printf("\n\nStudente trovato per nome.");
		printf("\nMedia voti> %f", media);
	}else if(parametro == 2){
		printf("\n\nStudente trovato per matricola.");
		printf("\nMedia voti> %f", media);
	}else{
		printf("\n\nStudente non trovato.");
	}
	return;
}

void StampaEsitoNegativo(){
	printf("studente non presente");
	return;
}

7 Risposte

  • Re: Warning funzione

    Perché nominativo non è di tipo char *
  • Re: Warning funzione

    L'ho fatto per una questione di comodità così che non c'è bisogno di allocare ogni volta la memoria in base alla lunghezza del nominativo, anche perchè così sarei stato costretto a prendere in input il nome + il \0 in modo tale da contare i caratteri e allocare una dimensione in memoria in base al numero dei caratteri.
  • Re: Warning funzione

    Rimane comunque sbagliato
  • Re: Warning funzione

    Perché?
  • Re: Warning funzione

    Leggendo il warning però pare che il problema sia legato al fatto che crei una copia di Studente all'interno della funzione, per poi ritornare l'indirizzo del nominativo che però una volta terminata la funzione non avrà piu senso (perchè puntava ad una copia), ma non ne sono sicuro. A breve leggo meglio tutto il codice e faccio qualche test
  • Re: Warning funzione

    Perché l'indirizzo è di una variabile locale che verrà distrutta all'uscita
  • Re: Warning funzione

    oregon ha scritto:


    Perché l'indirizzo è di una variabile locale che verrà distrutta all'uscita
    Condivido
Devi accedere o registrarti per scrivere nel forum
7 risposte