Dlaczego strumienie C++ używają char zamiast unsigned char?

Zawsze zastanawiałem się, dlaczego Biblioteka Standardowa C++ ma instancję strumienia basic_[io]i wszystkie jego warianty używając typu char zamiast typu unsigned char. char oznacza (w zależności od tego, czy jest podpisana, czy nie), że dla operacji takich jak get () można mieć przepełnienie i niedopełnienie, co doprowadzi do zdefiniowanej przez implementację wartości zmiennych. Innym przykładem jest, gdy chcesz wypisać bajt, Nieformatowany, do ostreama za pomocą jego funkcji put.

Any pomysły?


Uwaga: nadal nie jestem do końca przekonany. Więc jeśli znasz ostateczną odpowiedź, nadal możesz ją opublikować.

Author: Johannes Schaub - litb, 2008-11-10

4 answers

Prawdopodobnie źle zrozumiałem to pytanie, ale konwersja z unsigned char na char nie jest nieokreślona, jest zależna od implementacji (4.7-3 w standardzie C++).

Typ 1-bajtowego znaku w C++ to "char", a nie"unsigned char". Daje to implementacjom nieco większą swobodę w robieniu najlepszych rzeczy na platformie (na przykład organ standardów mógł wierzyć, że istnieją Procesory, w których arytmetyka bajtów podpisanych jest szybsza niż arytmetyka bajtów niepodpisanych, chociaż to spekulacje z mojej strony). Również dla kompatybilności z C. wynikiem usunięcia tego rodzaju niepewności egzystencjalnej z C++ jest C#; -)

Biorąc pod uwagę, że typ" char " istnieje, myślę, że ma sens dla zwykłych strumieni, aby go używać, mimo że jego znakowość nie jest zdefiniowana. Więc może na twoje pytanie odpowiada odpowiedź na pytanie: "dlaczego C++ nie zdefiniował char jako unsigned?"

 23
Author: Steve Jessop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-10 12:13:00

Zawsze rozumiałem to w ten sposób: celem klasy iostream jest odczytywanie i/lub zapisywanie strumienia znaków, które, jeśli się nad tym zastanowić, są abstrakcyjnymi bytami, które są reprezentowane tylko przez komputer przy użyciu kodowania znaków. Standard C++ sprawia wiele trudu, aby uniknąć przypinania kodowania znaków, mówiąc tylko, że "obiekty zadeklarowane jako znaki (char) powinny być wystarczająco duże, aby pomieścić dowolny element podstawowego zestawu znaków implementacji", ponieważ nie wymaga aby wymusić "implementacyjny podstawowy zestaw znaków" do zdefiniowania języka C++; standard może pozostawić decyzję , które kodowanie znaków jest używane w implementacji (kompilator wraz z implementacją STL), i tylko zauważyć, że obiekty char reprezentują pojedyncze znaki w niektórych kodowaniach.

Implementator może wybrać kodowanie jedno-oktetowe, takie jak ISO-8859-1 lub nawet kodowanie dwu-oktetowe, takie jak UCS-2 . Nieważne. Jako o ile obiekt char jest "wystarczająco duży, aby pomieścić dowolny element podstawowego zestawu znaków implementacji" (zauważ, że jawnie zabrania to kodowania o zmiennej długości), to implementacja może nawet wybrać kodowanie, które reprezentuje podstawową łacinę w sposób niezgodny z jakimkolwiek powszechnym kodowaniem!

Jest mylące, że char, signed char, i unsigned char rodzaje mają "char" w nazwach, ale ważne jest, aby pamiętać, że char nie należy do tej samej rodziny podstawowe typy jak signed char i unsigned char. signed char należy do rodziny typów całkowitych:

Istnieją cztery typy signed integer : "signed char", "short int", "int" i "long int."

I {[6] } należy do rodziny niepodpisanych typów całkowitych:

Dla każdego z podpisanych typów liczb całkowitych istnieje odpowiedni (ale inny) unsigned integer type : "unsigned char", "unsigned short int", "unsigned int" i " unsigned long int,"...

Jedno podobieństwo między char, signed char, i unsigned char typy są takie, że "[one] zajmują taką samą ilość pamięci i mają te same wymagania dotyczące dopasowania". Tak więc, można reinterpret_cast od char * do unsigned char * w celu określenia wartości liczbowej znaku w zestawie znaków wykonawczych.

Aby odpowiedzieć na twoje pytanie, powodem, dla którego STL używa char jako domyślnego typu jest to, że standardowe strumienie są przeznaczone do odczytu i / lub zapisu strumieni znaków, reprezentowane przez obiekty char, a nie liczby całkowite (signed char i unsigned char). Użycie char w stosunku do wartości liczbowej jest sposobem oddzielenia obaw.

 15
Author: Daniel Trebbien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-09 16:53:12

Char to znaki, unsigned char to surowe bajty danych, a signed char to, dobrze, signed data.

Standard nie określa, czy signed czy unsigned char będzie używany do implementacji char - jest specyficzny dla kompilatora. Określa tylko, że " char "będzie " wystarczająco", aby trzymać znaki w systemie - tak jak znaki były w tamtych czasach, czyli nie ma UNICODE.

Używanie "char" dla znaków jest standardowym sposobem. Używanie unsigned char to hack, chociaż będzie pasował do implementacji char kompilatora na większości platform.

 4
Author: n-alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-20 13:58:32

Myślę, że Ten komentarz dobrze to wyjaśnia. Cytat:

Signed char i unsigned char są typami arytmetycznymi, całkowitymi, podobnie jak int i unsigned int. Z drugiej strony, char ma być typem "I / O", który reprezentuje pewną nieprzezroczystą, specyficzną dla systemu podstawową jednostkę danych na twojej platformie. Użyłbym ich w tym duchu.

 0
Author: baruch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:56