|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Feb 2005
Messaggi: 579
|
[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: Codice:
#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);
}
1284629672649 (che è corretto) 1284629725184 (da CalcolaConsumi mi dà sempre questo valore fisso) Come mai, non è una variabile globale? |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Feb 2005
Messaggi: 579
|
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.
Codice:
void LeggiCounter()
{
ftime(&tempo);
TimeAnow = (float)tempo.time*1000+tempo.millitm;
printf("%.0f\n", TimeAnow); // CORRETTO
printf("%.0f\n", TimeAnow); // SBAGLIATO
}
Come mai printf mi modifica la variabile appena creata? |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Feb 2005
Messaggi: 579
|
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! Codice:
void LeggiCounter()
{
ftime(&tempo);
TimeAnow = (float)tempo.time*1000+tempo.millitm;
Sleep(100);
printf("%.0f\n", TimeAnow);
printf("%.0f\n", TimeAnow);
}
Ma cosa?? |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
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 Ultima modifica di tuccio` : 16-09-2010 alle 14:59. |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Feb 2005
Messaggi: 579
|
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? Ultima modifica di frank10 : 16-09-2010 alle 15:21. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
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 Ultima modifica di tuccio` : 16-09-2010 alle 15:29. |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Feb 2005
Messaggi: 579
|
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: Codice:
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);
}
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
il passaggio per riferimento è bene farlo dove è richiesta la modifica... la funzione
Codice:
void CalcolaConsumi(double *prova)
{
printf("%f\n",*prova);
}
Codice:
void CalcolaConsumi(double prova); Codice:
void CalcolaConsumi(const double *prova); in questo caso il passaggio per valore è la cosa migliore |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 12:12.


















