PDA

View Full Version : [Incomprensibilie C]--primi passi


kheper
08-12-2005, 13:54
Ciao a tutti...
Ho da poco iniziato con il C, scaricando alcuni corsi per principianti presenti online... fortunatamente ho anche un amico un po' più esperto che mi sta aiutando in questo avvio... ma sono sorti alcuni problemi che non sappiamo come risolvere.
Per farla breve, ho notato che alcuni programmi didattici presenti in quei corsi, mi danno dei risultati strambi, o addirittura non funzionano, così ho chiesto al mio amico di trovare gli eventuali errori e sorpresa, a lui funzionano correttamente! In pratica lo stesso codice, su 2 pc diversi produce 2 risultati diversi. Addirittura lo stesso programma compilato da lui (quindi un .exe) da lui produce un risultato e da me un altro.
Ovviamente parliamo di programmini semplicissimi, calcola media, stampa valori ecc ecc.
Il mio amico mi ha detto che potrebbe essere un problema relativo ai sistemi operativi, poichè lui usa linux e io xp.
Il compilatore è lo stesso per entrambi, e si tratta di DevC++.
Mi ha anche detto qualcosa tipo "il problema è che questi programmi cercano di accedere direttamente alla memoria, ma il Windows ci mette lo zampino e glielo impedisce, facendogli sballare tutti i valori".
Se volete posso anche postare il codice incrimato poichè si tratta di poche righe... ma ora mi chiedo, da programmatore che muove i primi passi, e non volendo abbandonare windows per linux solo per far girare correttamente un programma che calcola una media matematica, come devo procedere per essere sicuro che un codice scritto correttamente, funzioni in maniera corretta anche sul mio pc?
Grazie a tutti...

Gica78R
08-12-2005, 13:59
Addirittura lo stesso programma compilato da lui (quindi un .exe) da lui produce un risultato e da me un altro.

:confused:

Ma se lui lo compila sotto Linux, come puoi tu eseguire il binario sotto Win?

Cmq posta il sorgente, che sono curioso...

andbin
08-12-2005, 21:12
Il mio amico mi ha detto che potrebbe essere un problema relativo ai sistemi operativi, poichè lui usa linux e io xp.
Il compilatore è lo stesso per entrambi, e si tratta di DevC++.
Il Dev-C++, che io sappia (pur non avendolo mai usato), esiste solo per Windows. Quindi o il tuo amico non usa linux oppure non usa il Dev-C++. ;)

Se volete posso anche postare il codice incrimato poichè si tratta di poche righe...
Sarebbe meglio, potremmo capirci di più.

71104
08-12-2005, 21:31
Il Dev-C++, che io sappia (pur non avendolo mai usato), esiste solo per Windows. Quindi o il tuo amico non usa linux oppure non usa il Dev-C++. ;) probabilmente intendeva dire che il compilatore è il gcc (Dev-C++ usa MinGW).

kheper
08-12-2005, 23:03
probabilmente intendeva dire che il compilatore è il gcc (Dev-C++ usa MinGW).



Grazie a tutti per le risposte...
Aggiungo alcuni dettagli.
La mia versione di DevC++ è: 4.9.8.0,
mentre la sua è 4.9.9.2, oppure, quando usa il pc con linux, mi ha detto che "va direttamente di gcc".
Il codice incriminato è il seguente:

#include <stdio.h>

int main(void)
{
int numerucci[10];
int cont;
float media;

for (cont=0; cont<10; cont++)
{
printf("\nDammi il numero %d: ",cont);
scanf("%d",&numerucci[cont]); /* Scrivo nell'array */
}
for (cont=0; cont<10; cont++) media=media+numerucci[cont];

media /= 10;
printf("\nLa media tra i numeri introdotti e' %f.\n",media);
return(0);
}


copiato e incollato direttamente dal corso di C scaricato. l'unica variazione che ho effettuato è stata quella di sostituire il tipo della variabile "media" che in origine era "int", ma in entrambi i casi i risultati sono sballati, mentre a lui questo codice funziona perfettamente.
Come questo, anche altri miniprogrammi hanno dato risultati discordanti...

shinya
09-12-2005, 09:23
#include <stdio.h>

int main(void)
{
int numerucci[10];
int cont;
float media;


Sappi che se scrivi "float media" senza dare un valore, è molto probabile che il valore assegnato a quella variabile sia assolutamente casuale. Quindi quando dopo vai ad usarla con quel media = media + numerucci[cont] o quello che è, è probabile che usi un valore iniziale di 'media' che non avevi previsto. Penso, se la memoria non mi inganna, che questa questione lo standard la lasci alle singole implementazioni.
Cmq prova a dirgli

flot media = 0.0;

Louder Than Hell
09-12-2005, 10:57
Quoto shynia, il problema è quello ;)

Il devc++ eiste per:
Free Software (GPL)
For Windows 95, 98, NT, 2000, XP

Per cui magari il tuo amico usa ANCHE windows..anche perchè se no il suo eseguibile non funzionerebbe sul tuo windows ;)

kheper
09-12-2005, 11:22
Quoto shynia, il problema è quello ;)

Il devc++ eiste per:


Per cui magari il tuo amico usa ANCHE windows..anche perchè se no il suo eseguibile non funzionerebbe sul tuo windows ;)


Esatto.. nel primo post non avevo le idee molto chiare, ma nel secondo ho chiarito la doppia possibilità di cui lui dispone.

kheper
09-12-2005, 11:27
Sappi che se scrivi "float media" senza dare un valore, è molto probabile che il valore assegnato a quella variabile sia assolutamente casuale. Quindi quando dopo vai ad usarla con quel media = media + numerucci[cont] o quello che è, è probabile che usi un valore iniziale di 'media' che non avevi previsto. Penso, se la memoria non mi inganna, che questa questione lo standard la lasci alle singole implementazioni.
Cmq prova a dirgli

flot media = 0.0;


Non è un problema di inizializzazione in quanto sia inizializzata che no da esattamente lo stesso risultato.
Inoltre, il problema sussiste sia se sono io a compilare il codice, sia se utilizzo direttamente l'eseguibile passatomi dal mio amico (che, ripeto, a lui funziona perfettamente). In tutti i casi a me vien fuori sempre lo stesso risultato , e precisamente, un numero di 9 cifre se utilizzo una variabile int, un numero di più o meno 15 cifre con 4 decimali se utilizzo la variabile float...

Louder Than Hell
09-12-2005, 11:33
Non è un problema di inizializzazione in quanto sia inizializzata che no da esattamente lo stesso risultato.
Inoltre, il problema sussiste sia se sono io a compilare il codice, sia se utilizzo direttamente l'eseguibile passatomi dal mio amico (che, ripeto, a lui funziona perfettamente). In tutti i casi a me vien fuori sempre lo stesso risultato , e precisamente, un numero di 9 cifre se utilizzo una variabile int, un numero di più o meno 15 cifre con 4 decimali se utilizzo la variabile float...
Ma hai provato ad assegnare a media il valore 0 prima di fare la media? :mbe:

kheper
09-12-2005, 11:38
Ma hai provato ad assegnare a media il valore 0 prima di fare la media? :mbe:


Si, l'ho fatto.
Inoltre, il fatto che l'eseguibile compilato da lui, a lui funziona e a me da un risultato diverso, dovrebbe farti abbandonare definitivamente questa ipotesi.

Louder Than Hell
09-12-2005, 12:16
Si, l'ho fatto.
Inoltre, il fatto che l'eseguibile compilato da lui, a lui funziona e a me da un risultato diverso, dovrebbe farti abbandonare definitivamente questa ipotesi.
Be...se non fai media=0 è ovvio che a lui da un risultato diverso perchè dovrebbe essere psudocasuale cosi :D

Se fai anche media=0 allora non so :confused:

Gica78R
10-12-2005, 10:07
Non è un problema di inizializzazione in quanto sia inizializzata che no da esattamente lo stesso risultato.
Inoltre, il problema sussiste sia se sono io a compilare il codice, sia se utilizzo direttamente l'eseguibile passatomi dal mio amico (che, ripeto, a lui funziona perfettamente). In tutti i casi a me vien fuori sempre lo stesso risultato , e precisamente, un numero di 9 cifre se utilizzo una variabile int, un numero di più o meno 15 cifre con 4 decimali se utilizzo la variabile float...
Scusa, non ho capito del tutto quel che accade :stordita:
In pratica, il risultato che ottieni, a prescindere dal tipo di dato che utilizzi, e' corretto? Cioe', se fai la media inserendo dieci volte il valore 10, ottieni come risultato 10 (indipendentemente dalla precisione, nel caso dei float), oppure hai proprio risultati non corretti? :confused:

ciao

pietro84
10-12-2005, 12:11
Scusa, non ho capito del tutto quel che accade :stordita:
In pratica, il risultato che ottieni, a prescindere dal tipo di dato che utilizzi, e' corretto? Cioe', se fai la media inserendo dieci volte il valore 10, ottieni come risultato 10 (indipendentemente dalla precisione, nel caso dei float), oppure hai proprio risultati non corretti? :confused:

ciao

io ho capito che esce un numero completamente scorretto.
scusa ma dopo aver modificato il testo inizializzando la variabile media a 0 hai ricompilato? :mbe: a volte capitano queste sviste :D
l'unica causa di errore è attribuibile alla mancata inizializzazione di quella variabile. al max puoi sostituire "media/=10" con "media=media/10" che è più pulito...se non riesci e ho tempo provo a compilarlo anch'io.

pietro84
10-12-2005, 12:19
l'ho compilato su dev-c++ : se media non è inizializzato da logicamente problemi,inizializzando media a 0 e ricompilando funziona.

Gica78R
10-12-2005, 14:38
l'ho compilato su dev-c++ : se media non è inizializzato da logicamente problemi,inizializzando media a 0 e ricompilando funziona.
Io l'ho compilato su Mac con gcc 4.0 e ovviamente funziona (inizializzando media a zero). :rolleyes:

redcloud
10-12-2005, 15:00
Se inizializzo media a 0 e do in input 10 volte 1, il risultato è 1.000000.
Se non inizializzo media e do in input 10 volte 1, il risultato è 0.999997.

gcc version 4.0.3 20051201 (prerelease) (Debian 4.0.2-5)

Louder Than Hell
10-12-2005, 15:25
A me su linux funziona sia che faccia media = 0 sia che non lo faccia, non so se è merito di linux (ma non credo) :mbe:

pietro84
10-12-2005, 18:14
in ogni caso è scorretto non inizializzare la variabile media. la causa non può essere che questa.può darsi che gcc(non ricordo però se lo fa)inizializza automaticamente la variabile a 0,vedendo che non è inizializzata in nessuna riga di codice.

71104
11-12-2005, 00:06
Penso, se la memoria non mi inganna, che questa questione lo standard la lasci alle singole implementazioni. su Windows le variabili non inizializzate vengono sempre inizializzate automaticamente a 0 a meno che, come accade nel caso di kheper, non vengano scritte in locazioni "sporche" appena deallocate dallo stack: le variabili locali della main non inizializzate di conseguenza sono quasi sempre diverse da zero. :)

71104
11-12-2005, 00:11
in ogni caso è scorretto non inizializzare la variabile media. la causa non può essere che questa.può darsi che gcc(non ricordo però se lo fa)inizializza automaticamente la variabile a 0,vedendo che non è inizializzata in nessuna riga di codice. non è il gcc che la inizializza; se quella variabile è locale allora vuol dire che assume il valore 0 perché è stata allocata in una locazione ancora pulita dello stack (in allocazioni future e in chiamate successive alla stessa funzione potrebbe non assumere il valore 0: magari assume lo stesso valore che aveva alla fine dell'ultima chiamata...); se invece è globale allora il gcc l'ha messa in una sezione bss: tali sezioni hanno raw size nulla e virtual size non nulla; al caricamento del modulo PE il sistema operativo è tenuto ad allocare lo spazio indicato nel campo VirtualSize dell'header della sezione, e Windows quando alloca una pagina la azzera sempre tutta; inoltre anche se non lo facesse Windows la cosa è comunque obbligatoria perché è stabilita dalle specifiche del formato PE.

pietro84
11-12-2005, 11:15
non è il gcc che la inizializza; se quella variabile è locale allora vuol dire che assume il valore 0 perché è stata allocata in una locazione ancora pulita dello stack (in allocazioni future e in chiamate successive alla stessa funzione potrebbe non assumere il valore 0: magari assume lo stesso valore che aveva alla fine dell'ultima chiamata...); se invece è globale allora il gcc l'ha messa in una sezione bss: tali sezioni hanno raw size nulla e virtual size non nulla; al caricamento del modulo PE il sistema operativo è tenuto ad allocare lo spazio indicato nel campo VirtualSize dell'header della sezione, e Windows quando alloca una pagina la azzera sempre tutta; inoltre anche se non lo facesse Windows la cosa è comunque obbligatoria perché è stabilita dalle specifiche del formato PE.

si hai ragione non è il gcc che inizializza :D . cmq il programma deve essere scritto correttamente indipendentemente delle azioni che compie il sistema operativo,concordi che la causa dei numeri sballati sia la mancata inizializzazione della variabile media?

71104
11-12-2005, 11:53
si hai ragione non è il gcc che inizializza :D . cmq il programma deve essere scritto correttamente indipendentemente delle azioni che compie il sistema operativo,concordi che la causa dei numeri sballati sia la mancata inizializzazione della variabile media? perfettamente, ma dovevo pure sboroneggiare in qualche modo no? :D
comunque guarda che se uno sta facendo un programma che sa che dovrà far girare solo su Windows e usa variabili globali non inizializzate supponendo che queste siano inizializzate a 0 non succederà mai nulla di male :)
è una cosa da evitare per principio, ma di fatto non succede nulla di male ;)

pietro84
11-12-2005, 12:45
perfettamente, ma dovevo pure sboroneggiare in qualche modo no? :D
comunque guarda che se uno sta facendo un programma che sa che dovrà far girare solo su Windows e usa variabili globali non inizializzate supponendo che queste siano inizializzate a 0 non succederà mai nulla di male :)
è una cosa da evitare per principio, ma di fatto non succede nulla di male ;)

fino a un mese dopo aver fatto l'esame di S0 lo sapevo benissimo....ora questi concetti li ho un po messi da parte visto che sto studiando tutt'altro :D
comunque la variabile media è locale,e poi un programma potrebbe essere sempre ricompilato per altri sistemi operativi,non si sa mai :D

sottovento
12-12-2005, 09:39
E' evidente che la variabile deve essere inizializzata a zero poiche', senza dare spiegazioni tecniche troppo dettagliate, basta fare riferimento al manuale del linguaggio, il quale dice che le variabili non vengono inizializzate.
Ogni implementazione, quindi, puo' fare quello che vuole (inizializzare o meno).

Suggerimento su altre parti del programma: quando "mischi" numeri interi con numeri reali, devi stare attento all'insieme dei numeri che verranno utilizzati per effettuare l'operazione. Il manuale del linguaggio dice che verra' utilizzato l'insieme piu' ristretto.

In questo caso, va tutto bene, in altri programmini di esempio potresti avere problemi. Per esempio:

float a = b / c;

con b, c interi, la divisione sara' intera e subito dopo verra' fatta convertita in numero reale. Il risultato potrebbe non essere quello atteso.

In tal caso, devi forzare la conversione con l'operatore detto di casting:

float a = (float)b / (float)c;

Scusa se sono stato pedante

High Flying
Sottovento

kheper
16-12-2005, 10:52
Ragazzi negativo, non funziona nemmeno inizializzando la variabile... l'ho detto...
Inoltre, giriamo la questione:
Com'è possibile che uno stesso eseguibilie, su di un pc produce un risultato e su di un altro pc ne produce un altro?

71104
16-12-2005, 10:54
Ragazzi negativo, non funziona nemmeno inizializzando la variabile... l'ho detto...
Inoltre, giriamo la questione:
Com'è possibile che uno stesso eseguibilie, su di un pc produce un risultato e su di un altro pc ne produce un altro? le possibilità sono infinite: hardware differente, temporizzazione, differenze di implementazione di qualche libreria, race conditions...
nel tuo caso... aspetta che non ho ancora letto il sorgente :D

71104
16-12-2005, 10:58
boh, a me inizializzando la media funziona... che output da a te?

EnderIII
16-12-2005, 11:46
Prova questa modifica:

scanf("%d\n",&numerucci[cont]);