Domanda

Mi sono sempre chiesto perché la libreria C ++ Standard ha istanziato lo stream basic_ [io] e tutte le sue varianti usando il tipo char invece del tipo unsigned char . char significa (a seconda che sia firmato o meno) puoi avere overflow e underflow per operazioni come get (), che porteranno al valore definito dall'implementazione delle variabili coinvolte. Un altro esempio è quando si desidera inviare un byte, non formattato, a uno ostream usando la sua funzione put .

Qualche idea?


Nota : non sono ancora molto convinto. Quindi, se conosci la risposta definitiva, puoi comunque pubblicarla.

È stato utile?

Soluzione

Forse ho frainteso la domanda, ma la conversione da char senza segno a char non è non specificata, dipende dall'implementazione (4.7-3 nello standard C ++).

Il tipo di carattere a 1 byte in C ++ è "char", non "unsigned char". Ciò offre alle implementazioni un po 'più di libertà di fare la cosa migliore sulla piattaforma (ad esempio, il corpo degli standard potrebbe aver creduto che esistessero CPU in cui l'aritmetica di byte con segno è più veloce dell'aritmetica di byte senza segno, anche se questa è la mia speculazione). Anche per compatibilità con C. Il risultato della rimozione di questo tipo di incertezza esistenziale da C ++ è C # ;-)

Dato che il " char " esiste un tipo, penso che abbia senso usarlo per i soliti stream anche se la sua firma non è definita. Quindi forse la tua domanda risponde alla risposta a, " perché C ++ non ha semplicemente definito char come unsigned? & Quot;

Altri suggerimenti

L'ho sempre capito in questo modo: lo scopo della classe iostream è leggere e / o scrivere un flusso di caratteri, che, se ci pensate, sono entità astratte che sono solo rappresentato dal computer utilizzando una codifica dei caratteri. Lo standard C ++ fa di tutto per evitare di fissare la codifica dei caratteri, dicendo solo che gli oggetti dichiarati come caratteri ( char ) devono essere abbastanza grandi da contenere qualsiasi membro del set di caratteri di base dell'implementazione, " perché non è necessario forzare il set di caratteri di base dell'implementazione " " definire il linguaggio C ++; lo standard può lasciare la decisione di quale codifica dei caratteri viene utilizzata per l'implementazione (compilatore insieme a un'implementazione STL) e basta notare che gli oggetti char rappresentano singoli caratteri in alcune codifiche .

Un autore di implementazione potrebbe scegliere una codifica a singolo ottetto come ISO-8859-1 o persino una codifica a doppio ottetto come UCS-2 . Non importa Finché un oggetto char è " abbastanza grande da contenere qualsiasi membro del set di caratteri di base dell'implementazione " (tieni presente che ciò proibisce esplicitamente codifiche a lunghezza variabile ), quindi l'implementazione può persino scegliere un codifica che rappresenta il latino di base in un modo incompatibile con qualsiasi codifica comune!

È confuso che i tipi char , firmato char e unsigned char condividano " char " nei loro nomi, ma è importante tenere presente che char non appartiene alla stessa famiglia di tipi fondamentali di char char firmato e char unsigned . firmato char appartiene alla famiglia dei tipi interi firmati:

  

Esistono quattro tipi di numeri interi con segno : " carattere con segno " ;, " short int " ;, " int " ;, e " long int. "

e carattere senza segno appartiene alla famiglia dei tipi di numeri interi senza segno:

  

Per ciascuno dei tipi di numeri interi con segno, esiste un tipo di numero intero senza segno corrispondente (ma diverso) : " unsigned char " ;, " unsigned short int " ;, " unsigned int " ;, e " unsigned long int, " ...

L'unica somiglianza tra i tipi char , firmato char e unsigned char è che [quotano] occupano la stessa quantità di archiviazione e avere gli stessi requisiti di allineamento ". Pertanto, è possibile reinterpret_cast da char * a unsigned char * per determinare il valore numerico di un carattere nel set di caratteri di esecuzione.

Per rispondere alla tua domanda, il motivo per cui l'STL utilizza char come tipo predefinito è perché i flussi standard sono pensati per leggere e / o scrivere flussi di caratteri, rappresentati da char oggetti, non numeri interi ( char firmato e char unsigned ). L'uso di char rispetto al valore numerico è un modo per separare le preoccupazioni.

char è per caratteri, char senza segno per byte di dati non elaborati e caratteri firmati per, beh, dati firmati.

Lo standard non specifica se per l'implementazione del carattere verrà utilizzato il carattere con segno o senza segno: è specifico del compilatore. Specifica solo che il "carattere" sarà " abbastanza " per trattenere i personaggi sul tuo sistema - il modo in cui i personaggi erano in quei giorni, ovvero UNICODE.

Utilizzo di " char " per i personaggi è il modo standard di procedere. L'uso di char senza segno è un hack, sebbene corrisponderà all'implementazione del char del compilatore sulla maggior parte delle piattaforme.

Penso che questo commento lo spiega bene. Per citare:

  

char char e unsigned char sono aritmetici, tipi integrali proprio come int e unsigned int. D'altra parte, char è espressamente inteso come "I / O" tipo che rappresenta un'unità fondamentale di dati opaca specifica per il sistema sulla tua piattaforma. Li userei in questo spirito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top