Salta al contenuto
Tiantan
Articles

Memorizzazione del carattere EOF (End of File) in un carattere di tipo

Su Febbraio 18, 2021 da admin

Ho letto nel linguaggio di programmazione C di Dennis Ritchie prenota che int deve essere utilizzato affinché una variabile contenga EOF – per renderla sufficientemente grande in modo che possa contenere il valore EOF – non char. Ma il seguente codice funziona bene:

#include<stdio.h> main() { char c; c=getchar(); while(c!=EOF) { putchar(c); c=getchar(); } } 

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

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

Commenti

  • Nessun carattere EOF.
  • È probabile che questo codice non vada a buon fine se leggi un carattere con il valore 0xff. Memorizzazione del risultato di getchar() in un int risolve il problema. La tua domanda è essenzialmente la stessa della domanda 12.1 nelle comp.lang.c FAQ , che è unottima risorsa. (Inoltre, main() dovrebbe essere int main(void) e non ' non fa male aggiungere un return 0; prima della chiusura }.)
  • @delnan: larticolo collegato non è ' Ha ragione su come Unix tratta control-D. Non ' chiude il flusso di input; fa semplicemente sì che qualsiasi fread () che si sta bloccando sulla console ritorni immediatamente con qualsiasi dato non ancora letto. Molti programmi interpretano un ritorno a zero byte da fread () come indicante EOF, ma il file rimarrà in effetti aperto e in grado di fornire più input.

Risposta

Il tuo codice sembra funzionare, perché le conversioni di tipo implicite si verificano accidentalmente per fare la cosa giusta.

getchar() restituisce un int con un valore che rientra nellintervallo di unsigned char o è EOF ( che deve essere negativo, di solito è -1). Tieni presente che EOF in sé non è un carattere, ma un segnale che non ci sono più caratteri disponibili.

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

Il passaggio successivo consiste nel confrontare c con EOF. Poiché EOF è anche un int, c verrà convertito in un int, preservando il valore memorizzato in c. Se c può memorizzare il valore di EOF, il confronto avrà esito positivo , ma se c è stato in grado di non memorizzare il valore, il confronto non riuscirà, perché si è verificata una perdita irreversibile di informazioni durante la conversione di EOF per digitare char.

Sembra che il tuo compilatore abbia scelto di impostare il tipo char firmato e il valore di EOF piccolo abbastanza per entrare in char. Se char non fosse firmato (o se avessi utilizzato unsigned char), il test sarebbe fallito, perché unsigned char non può “mantenere il valore di EOF.


Nota inoltre che cè un secondo problema con il tuo codice. Come EOF non è un carattere in sé, ma lo forzi in un tipo char, molto probabilmente cè un carattere là fuori che viene interpretato erroneamente come EOF e per metà dei caratteri possibili non è definito se verranno elaborati correttamente.

Commenti

  • Coercizione per digitare char valori al di fuori dellintervallo CHAR_MIN .. CHAR_MAX sarà necessario per fornire un valore definito dallimplementazione, restituisce un modello di bit che limplementazione definisce come una rappresentazione trap o genera un segnale definito dallimplementazione. Nella maggior parte dei casi, le implementazioni dovrebbero fare molto lavoro extra per fare qualcosa di diverso da due ' riduzione del complemento a s.Se le persone del Comitato per gli standard sottoscrissero lidea che i compilatori dovrebbero essere incoraggiati a implementare comportamenti coerenti con quelli della maggior parte degli altri compilatori in assenza di motivi per fare altrimenti …
  • … coercizione come affidabile (per non dire che il codice non dovrebbe ' t documentare le sue intenzioni, ma che (signed char)x dovrebbe essere considerato più chiaro e altrettanto sicuro come ((unsigned char)x ^ CHAR_MAX+1))-(CHAR_MAX+1).) Così comè, ' non vedo alcuna probabilità che i compilatori implementino qualsiasi altro comportamento conforme agli attuali ' standard; lunico pericolo sarebbe che lo standard potesse essere modificato per interrompere il comportamento nel presunto interesse di " ottimizzazione ".
  • @supercat: lo standard è scritto in modo tale che nessun compilatore debba produrre codice che abbia un comportamento che non è naturalmente supportato dal processore a cui si rivolge. La maggior parte del comportamento indefinito è presente perché (al momento della stesura dello standard) non tutti i processori si sono comportati in modo coerente. Con i compilatori che diventano più maturi, gli autori di compilatori hanno iniziato a sfruttare il comportamento indefinito per fare ottimizzazioni più aggressive.
  • Storicamente, lintenzione dello Standard era principalmente come tu descrivi, sebbene lo Standard descriva alcuni comportamenti in dettagli sufficienti da richiedere ai compilatori di alcune piattaforme comuni di generare più codice di quanto sarebbe richiesto con una specifica più ampia. Il tipo di coercizione in int i=129; signed char c=i; è uno di questi comportamenti. Relativamente pochi processori hanno unistruzione che renderebbe c uguale a i quando ' è in lintervallo compreso tra -127 e +127 e produrrebbe qualsiasi mappatura coerente di altri valori di i con valori compresi tra -128 e +127 diversi da due ' riduzione del complemento a s, o …
  • … solleverebbe costantemente un segnale in questi casi. Poiché lo standard richiede che le implementazioni producano una mappatura coerente o generino costantemente un segnale, le uniche piattaforme in cui lo standard lascerebbe spazio per qualcosa di diverso da due ' riduzione del complemento a s sarebbero cose come i DSP con hardware aritmetico saturante. Per quanto riguarda la base storica di Undefined Behavior, direi che il problema non è ' solo con piattaforme hardware. Anche su una piattaforma in cui loverflow si comporterebbe in modo molto coerente, può essere utile che un compilatore lo intrappoli …

Scritto da admin

Lascia un commento Annulla risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Articoli recenti

  • Utilizzando un balun con un dipolo risonante
  • Qual è la differenza tra “ non può ” e “ non può ”? [duplicate]
  • Al JFK, puoi muoverti tra i terminal airside sui voli nazionali?
  • “ Molto apprezzato ” o “ molto apprezzato ”
  • Che cosa significa ' idee astratte '? [chiuso]

Archivi

  • Febbraio 2021
  • Gennaio 2021
  • Dicembre 2020
  • Novembre 2020
  • Deutsch
  • Nederlands
  • Svenska
  • Norsk
  • Dansk
  • Español
  • Français
  • Português
  • Italiano
  • Română
  • Polski
  • Čeština
  • Magyar
  • Suomi
  • 日本語
  • 한국어

Testo del copyright Tiantan 2021 | Theme by Theme in Progress | Proudly powered by WordPress

Torna Su