View Full Version : [C] variabile modificata da funzione
Sono nuovo del C, forse questa è una banalità, portate pazienza.
Ho una variabile globale che cambia all'interno di una funzione.
Da un'altra funzione, voglio leggere quel valore, ma me ne dà un altro:
ad esempio, semplificando:
#include <stdio.h>
#include <time.h>
#include <sys/timeb.h>
#include <windows.h>
void CalcolaConsumi( float );
void LeggiCounter();
float TimeAnow=0;
struct timeb tempo;
int main(short argc, char **argv)
{
int goLoop = 1;
int timer = atoi(argv[1]);
while (goLoop)
{
LeggiCounter();
CalcolaConsumi( TimeAnow);
Sleep( timer );
}
}
void LeggiCounter()
{
ftime(&tempo);
TimeAnow = (float)tempo.time*1000+tempo.millitm;
printf("%.0f\n", TimeAnow);
}
void CalcolaConsumi(float prova)
{
printf("%.0f\n", prova);
}
mi dà TimeAnow=
1284629672649 (che è corretto)
1284629725184 (da CalcolaConsumi mi dà sempre questo valore fisso)
Come mai, non è una variabile globale?
Ho scoperto che mettendo un altro printf all'interno della prima funzione LeggiCounter, dove cambia il valore della variabile, mi dà anche lì il risultato sbagliato.
void LeggiCounter()
{
ftime(&tempo);
TimeAnow = (float)tempo.time*1000+tempo.millitm;
printf("%.0f\n", TimeAnow); // CORRETTO
printf("%.0f\n", TimeAnow); // SBAGLIATO
}
Allora non c'entra il passaggio ad un'altra funzione, ma la funzione printf che mi modifica la variabile.
Come mai printf mi modifica la variabile appena creata?
Altra scoperta:
Aggiungendo uno Sleep(100); dopo la modifica della variabile, essa rimarrà sempre a un valore fisso anche alle successive chiamate! Non sarà più corretta!
void LeggiCounter()
{
ftime(&tempo);
TimeAnow = (float)tempo.time*1000+tempo.millitm;
Sleep(100);
printf("%.0f\n", TimeAnow);
printf("%.0f\n", TimeAnow);
}
A questo punto, non è neppure printf...
Ma cosa??
visto che non ha molto senso l'errore, probabilmente è un overflow, d'altronde non capisco perché usare il tipo float per valori interi positivi, per me con unsigned int funzionerà tutto :E
ps: che bruttezza tutte quelle variabili globali
Avevo usato float perché, essendo in ms, poi dividevo per 1000 per avere i secondi e devo sottrarre un altro valore per vedere la differenza e lì mi serve la virgola per avere un po' di corretta approssimazione.
Comunque sì, ho provato a mettere int e funziona.
Con int e i secondi non riuscirei ad avere abbastanza precisione.
Allora ho lasciato la lettura del tempo in ms in int e poi successivamente ho convertito in float per avere i secondi con la virgola.
Ottimo, grazie.
Bè, nell'esempio, ne ho messa solo una... dato che timeb è dentro un include.
Tu come faresti avendo parecchie variabili da aggiornare?
Passarle tutte tra funzioni con i return?
o passaggio per riferimento..
comunque TimeAnow e tempo sono due variabili globali, che intendi per "è dentro un include"?
in generale, comunque, evitare le variabili globali è una regola di buona programmazione
ps: comunque se ritieni corretta la scelta di usare una variabile in virgola mobile, c'è sempre il tipo double
Ho provato con double e funziona bene.
Quindi è solo il float a dare quei problemi. Strano.
Ho letto un po' sui puntatori (non li avevo fatti prima).
Quindi, togliendo le var globali, passare per riferimento, sarebbe ad esempio:
void LeggiCounter(double *pTime);
void CalcolaConsumi(double *prova);
int main(short argc, char **argv)
{
double TimeAnow=0;
int goLoop = 1;
int timer = atoi(argv[1]);
while (goLoop)
{
LeggiCounter(&TimeAnow );
printf("%f___\n", TimeAnow);
CalcolaConsumi( &TimeAnow );
Sleep( timer );
}
}
void LeggiCounter(double *pTime)
{
struct timeb tempo;
ftime(&tempo);
*pTime = (double)tempo.time*1000+tempo.millitm;
printf("%f\n", *pTime);
}
void CalcolaConsumi(double *prova)
{
printf("%f\n",*prova);
}
il passaggio per riferimento è bene farlo dove è richiesta la modifica... la funzione
void CalcolaConsumi(double *prova)
{
printf("%f\n",*prova);
}
non modifica il valore della variabile, e questo dovrebbe trasparire dall'intestazione della funzione.. un'intestazione del tipo
void CalcolaConsumi(double prova);
oppure
void CalcolaConsumi(const double *prova);
"dice" che la variabile non verrà modificata (perché non puoi farlo nella funzione)
in questo caso il passaggio per valore è la cosa migliore
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.