2015-12-16 7 views
5

Sto cercando di eseguire il codice seguente:C- ciclo while non-ha spiegato il comportamento

#include <sys/time.h> 
#include <stdio.h> 

int main() 
{ 
unsigned int ms, oldms = 0,dif; 
struct timeval tv; 
while(1) 
{ 
gettimeofday(&tv, NULL); 
ms=tv.tv_sec; 
//printf("%d\n",ms-oldms); 
dif=ms-oldms; 
if(dif>3) 
    {  
     printf("3 seconds up"); 
     oldms=ms; 
    } 
} 
} 

mi aspetto per stampare "3 secondi up" dopo ogni 3 secondi, ma non visualizza che Messaggio. Ho provato a eseguirne il debug usando gdb ma non sembra nulla di sbagliato e ancora nessun output. Durante il tentativo di eseguire il debug, ho aggiunto una dichiarazione printf e magicamente è possibile vedere l'output.

Se eseguo il programma dopo aver rimosso // printf ("% d \ n", ms-oldms); dichiarazione, non c'è ancora uscita. Non sono sicuro di cosa sta succedendo e se dipende da qualcosa.

$ gcc --version gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

+4

Prova a mettere una nuova riga sul vostro printf – Jorgel

+0

@Jorgel, mettendo un ritorno a capo in printf funzionato. Ma, sono ancora confuso su questo comportamento. Questa è la prima volta che ho incontrato questo. – kid

+0

Hai un loop infinito - questa è la "prima volta". Anche senza newline funzionerà OK se aggiungi 'break' dopo' printf'. – i486

risposta

10

buffer di uscita è la ragione.

stdout è una linea bufferizzata per impostazione predefinita quando collegata a un dispositivo terminale. È possibile eseguire il flush out utilizzando fflush(stdout); o utilizzando \n in printf(), ad esempio printf("3 seconds up\n");. o disabilitarlo con setbuf(stdout, 0);

I/O è lento in generale. Quindi le implementazioni usano un buffer di dimensioni fisse e printf una volta che si riempie. In pratica, chiamare troppo spesso fflush(stdout); può influire sulle prestazioni.

+0

Quindi questo problema riguarda il printf giusto? da vostro figlio suppongo che non ci sia nulla di sbagliato nel ciclo while o nel grande volume di elaborazione che si verifica nel codice. – kid

+0

Sì. Niente di sbagliato con il ciclo. Ma non direi che è un "problema". C'è una buona ragione per cui le implementazioni di libc fanno il buffering: le prestazioni. –

+0

o printf ("3 secondi su \ n"); o printf ("\ n3 secondi su"); non ha funzionato Anche l'aggiunta di un nuovo printf ("\ n") prima che printf ("3 secondi su \ n") non ha aiutato. Il codice funziona correttamente se inserisco un printf ("\ n") al posto del printf commentato (// printf ("% d \ n", ms-oldms);) nel codice – kid

1

il codice pubblicato ha un paio di problemi

  1. la variabile oldms non è essere impostato su qualsiasi valore specifico prima che il tempo trascorso è in corso di verifica
  2. senza né una chiamata a fflush(stdout); o un fine riga ('\ n') nella stringa di formato, nulla sarà uscita (per un tempo molto lungo, finché il buffer è pieno sistema stdout)
  3. di leggibilità, l'assioma only one statement per line and (at most) one variable declaration per statement viene applicata al codice

il seguente codice viene compilato in modo pulito ed esegue l'operazione desiderata

#include <sys/time.h> 
#include <stdio.h> 

int main() 
{ 
    unsigned int ms; 
    unsigned int oldms = 0; 
    unsigned int dif; 
    struct timeval tv; 

    gettimeofday(&tv, NULL); 
    oldms = tv.tv_sec; 

    while(1) 
    { 
     gettimeofday(&tv, NULL); 
     ms=tv.tv_sec; 
     //printf("%d\n",ms-oldms); 
     dif=ms-oldms; 

     if(dif>3) 
     { 
      printf("3 seconds up\n"); 
      oldms=ms; 
     } 
    } 
} // end function: main