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ć.
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?"
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.
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.
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.
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