Dubbio su un programma in linguaggio c

deian91
sto provando a risolvere il programma in C presente su questo file: http://www.diee.unica.it/~marcialis/FI1/mie/esami/110610.pdf

ho qualche dubbio:

la funzione leggi_punto, deve leggere le cordinate dei punti presenti sul file input.txt (e in questo caso non ci dovrebbe essere un contatore per individuare quali cordinate leggere?) oppure deve leggere le cordinate del punto inserito da tastiera (e in questo caso perchè c'è un FILE*fp in ingresso?)??

Risposte
apatriarca
Deve leggere dallo stream che gli viene passato (rappresentato dalla variabile di tipo FILE* che ha come parametro). Per usarla per leggere il punto da tastiera è sufficiente passare stdin* come argomento alla funzione. La funzione si riduce praticamente ad fscanf.

* Ho appena notato che si sono le soluzioni più avanti. Il commento del tuo professore
/*oppure: b=leggi_punto(stdout);*/

è SBAGLIATO... stdout è lo standard output e serve appunto per l'output e quindi per stampare qualcosa sulla console. stdin è invece lo standard input ed è quello che deve essere usato per la lettura dei valori da console.

Rggb1
@apatriarca
L'avevo notato anche io, mi pareva strano ti fosse sfuggito :-D E magari ce ne sono altri. :\

/OT
Ma come si fa a fare 'sti minestroni mal assortiti come "esami"?
TO/

apatriarca
Non è neanche l'unico problema del codice del professore. Ma non mi sembrava il caso di fare troppe polemiche, essendo alcuni di questi problemi insiti nel testo stesso del problema. Per esempio:
f=fopen(“input.txt”,”r”);
fscanf(f,“%d”,&n);
for(i=0; i<n; i++)
p[i]=leggi_punto(f);
fclose(f);

Manca il controllo che il file venga aperta correttamente, che la lettura avvenga correttamente e che il numero letto abbia senso (che non sia ad esempio negativo) e che sia minore della dimensione massima del punto. Tutto questi problemi potrebbero portare ad un crash o ad un comportamento anomalo (cicli infiniti, valori incomprensibili o cose simili). Il codice corretto avrebbe dovuto essere qualcosa tipo:
f = fopen("input.txt", "r");
if (f == NULL) {
    fprintf(stderr, "Impossibile aprire il file.\n\n");
    return 1; 
}

fscanf(f, "%u", &n); /* non ha senso che n possa essere negativo.. dovrebbe anche essere definito come unsigned e inizializzato. */

if (n >= N) {
    fprintf(stderr, "Impossibile elaborare più di %u punti.\n\n", N);
    return 2;
}

for(i=0; i<n; i++) {
    p[i]=leggi_punto(f);
}

fclose(f);

Alternativamente si sarebbe dovuto invertire la lettura del punto e quella del file in modo da poter trovare il punto più vicino senza dover memorizzare i punti in un array. Ma tutto ciò va probabilmente oltre gli obiettivi del corso.

deian91
ok ok.
spero di riuscire a capire qualcosa al più presto. secondo me sono anche poco chiari i testi d'esame ma probabilmente è solo una mia impressione...

vict85
"Rggb":
/OT
Ma come si fa a fare 'sti minestroni mal assortiti come "esami"?
TO/


/OT
Tra l'altro in un solo esame passa dai sistemi operativi, alla logica booleana, ai database alle operazioni con i float... Ma c'è una triennale di informatica là dentro... come fa a pensare che gli studenti possano imparare qualcosa se fa tante cose insieme e neanche molto bene :roll:
TO/

deian91
ho un dubbio anche su una funzione di questo programma:http://www.diee.unica.it/~marcialis/FI1/mie/esami/100903.pdf

nella funzione calcola_minimo, l'uscita non dovrebbe essere il voto corrispondente al "minimo" prodotto fra voto e crediti della componente i-esima del vettore punteggi p??

apatriarca
"deian91":
ho un dubbio anche su una funzione di questo programma:http://www.diee.unica.it/~marcialis/FI1/mie/esami/100903.pdf

nella funzione calcola_minimo, l'uscita non dovrebbe essere il voto corrispondente al "minimo" prodotto fra voto e crediti della componente i-esima del vettore punteggi p??

Sì, dovrebbe essere così. Ma il codice sembra in effetti fare quello. Sta indubbiamente cercando il minimo e non capisco quindi come possa essergli uscito 29 con quell'input e quel programma. Forse quello non è il risultato del programma, ma una soluzione che ha scritto quando si inventava il problema e nello scriverlo si è confuso tra minore e maggiore. L'unica cosa strana che noto nella funzione calcola_minimo è di inizializzare minpr a 30. È un numero molto basso.. Normalmente si dovrebbe inizializzare ad un numero più alto di tutti quelli che posso eventualmente essere presenti. 30 è basso e forse nello scriverlo ha pensato al massimo dei voti e non ai voti moltiplicati per i crediti. Un numero più sensato poteva essere il massimo valore rappresentabile in una variabile intera (che poteva anche essere unsigned)*, ma pensando al nostro sistema scolastico anche 30*60 poteva andare bene (è già insensato ma escludere la possibilità anche di corsi di 20-30 crediti sarebbe stato esagerato e questo numero è comunque molto inferiore al massimo valore rappresentabile da un intero. Ma non ci sono comunque molti vantaggi nello scegliere un numero al posto di un altro. Un'altra scelta possibile sarebbe stata quella di prendere il prodotto voto-crediti del primo elemento direttamente (verificando in precedenza che fosse stato letto almeno un elemento).

* Inizio a pensare che non vi abbia insegnato a lavorare con gli interi senza segno...

P.S. :-D Questa volta ci ha pensato al controllo degli errori.. :roll:

deian91
ah, ok. però se all'esame mi ritrovo qualcosa del genere è un problema.
non mi riferisco solo all'esempio; nelle indicazioni per le funzioni dice:
"Funziona calcola_minimo con
* tipo in ingresso: una variabile p di tipo vettore_punteggi e un intero corrispondente al
numero di punteggi di p;
* tipo in uscita: intero, ovvero il voto corrispondente al massimo prodotto tra i voti e i relativi
crediti di ciascuna componente di p.

deian91
in un altro compito dice:

"Funzione leggi_interi con:
• tipo in ingresso: stringa indicante il nome_file da aprire e una variabile di tipo
tipo_voto chiamata voti;
• tipo in uscita: intero.
La funzione legge dal file chiamato nome_file una sequenza di interi, e la memorizza in
voti. Restituisce il numero di interi letti."

la soluzione riportata dal docente è:

int leggi_interi(char* nome_file, tipo_voto voti)
{
FILE *fp;
int n;
n=0;
fp=fopen(nome_file,”r”);
while((!feof(fp))&&(n {
fscanf(fp,”%d”,&voti[n]);
n++;
}
fclose(fp);
return n;
}


non dovrebbe essere:


n=n-1;
return n;

apatriarca
Non avevo notato che anche nel testo del problema c'erano ulteriori problemi. In questo caso la cosa da fare è chiedere chiarimenti al professore in sede d'esame facendogli notare il problema nel testo. Per il tuo secondo dubbio è corretto restituire n. n-1 sarebbe l'indice dell'ultimo elemento e non il numero di elementi letti (che parte dall'indice 0).

deian91
in questo compito http://www.diee.unica.it/~marcialis/FI1/mie/esami/110610.pdf

la funzione trova_minima_distanza è stata risolta dal docente così:

int trova_minima_distanza(vettore_punti p, int n, tipo_punto b)
{
int i, minp;
float mind, d;
tipo_punto b;
minp=0;
mind=calcola_distanza(b,p[0]);
for(i=1; i<n; i++)
{
d=calcola_distanza(b,p[i]);
if(d<mind)
{
mind=d;
minp=i;
}
}
return minp;
}


a cosa serve dichiarare tipo_punto b se si trova già in entrata?

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.