Memorizzazione del carattere EOF (Fine del file) in un tipo di carattere

9

Ho letto nel libro The C Programming Language di Dennis Ritchie che int deve essere usato per una variabile per contenere EOF - per renderlo sufficientemente grande in modo che possa contenere il valore EOF - non% codice%. Ma il codice seguente funziona bene:

#include<stdio.h> 

main()  { 
  char c; 
  c=getchar(); 
  while(c!=EOF)  { 
    putchar(c); 
    c=getchar(); 
  } 
} 

Quando non c'è più input, char restituisce EOF. E nel programma precedente, la variabile getchar , con tipo char, è in grado di mantenerla correttamente.

Perché funziona? Come da spiegazione nel libro sopra menzionato, il codice non dovrebbe funzionare.

    
posta user1369975 10.05.2013 - 10:36
fonte

1 risposta

11

Il tuo codice sembra funzionare, perché le conversioni di tipo implicito accidentalmente capita di fare la cosa giusta.

getchar() restituisce un int con un valore che rientra nell'intervallo di unsigned char o è EOF (che deve essere negativo, di solito è -1). Nota che EOF non è un personaggio, ma segnala che non ci sono più caratteri disponibili.

Quando si memorizza il risultato da getchar() in c , ci sono due possibilità. O il tipo char può rappresentare il valore, nel qual caso è il valore di c . Oppure il tipo char non può rappresentare il valore. In tal caso, non è definito cosa accadrà. I processori Intel tagliano solo i bit alti che non si adattano al nuovo tipo (riducendo efficacemente il valore modulo 256 per char ), ma non dovresti fare affidamento su questo.

Il prossimo passo è confrontare c con EOF . Poiché EOF è un int , c verrà convertito anche in int , preservando il valore memorizzato in c . Se c potrebbe memorizzare il valore di EOF , allora il confronto avrà successo, ma se c potrebbe non memorizzare il valore, allora il confronto fallirà, perché c'è stata una perdita irrecuperabile di informazioni durante la conversione di EOF nel tipo char .

Sembra che il compilatore abbia scelto di rendere il tipo char firmato e il valore di EOF abbastanza piccolo da rientrare in char . Se char non era firmato (o se hai utilizzato unsigned char ), il tuo test sarebbe fallito, perché unsigned char non può contenere il valore di EOF .

Nota anche che c'è un secondo problema con il tuo codice. Poiché EOF non è un personaggio stesso, ma lo imponi in un tipo char , è molto probabile che un personaggio là fuori venga interpretato erroneamente come EOF e per metà dei possibili caratteri non è definito se saranno elaborato correttamente.

    
risposta data 10.05.2013 - 11:50
fonte

Leggi altre domande sui tag