2011-01-14 16 views
9

Jaki jest sens ujemnych wartości ASCII?Ujemna wartość ASCII

int a = '«'; //a = -85 but as in ASCII table '<<' should be 174 
+13

kody ASCII tylko iść od 0 - 127. –

+8

Zauważ, że ASCII jest ważna tylko do wartości w zakresie od 0 ..127. Tak zwany * rozszerzony ASCII * zawiera wartości z 128..255 i widzisz właśnie taką wartość wyrażoną tutaj jako znakowany znak. –

+1

"Tak zwany rozszerzony ASCII" nie istnieje. Jednak kodowania jednobajtowe. – n0rd

Odpowiedz

3

Nie ma czegoś takiego. ASCII to tablica znaków, każda postać ma indeks lub pozycję w tabeli. Nie ma żadnych "negatywnych" wskaźników.

Niektóre kompilatory uważają jednak, że char jest oznaczonym, integralnym typem danych, co prawdopodobnie stanowi przyczynę zamieszania.

Jeśli wydrukujesz je jako unsigned int, otrzymasz te same bity interpretowane jako niepodpisane (dodatnie) wartości.

+1

masz na myśli 'unsigned char'? – user963241

10

To jest artefaktem kompilator za char typu bycia typ podpisał całkowitą, a int jest szersza podpisał typ całkowitą, a tym samym stała postać jest traktowana jako liczba ujemna i wynosi logowania przedłużony do szerszego typu całkowitego .

Nie ma w tym większego sensu, po prostu się dzieje. Standard C pozwala na implementacje kompilatorów, aby wybrać, czy uważają one za podpisane czy niepodpisane char. Niektóre kompilatory mają nawet przełączniki czasu kompilacji, aby zmienić domyślne. Jeśli chcesz się upewnić, że jest to sygnatura typu char, napisz jednoznacznie: signed char lub unsigned char.

Użyć unsigned char zostać przedłużony do int aby uniknąć negatywnego wartość int lub otworzyć zupełnie nowy puszkę Pandory i cieszyć wchar.

+2

Nie, to dlatego, że postać nie pasuje do literału. Problem pojawia się * przed * "int" nawet pojawia się w obrazie. Literał kończy się wartością -85 z powodu przepełnienia, a następnie ta wartość -85 jest przypisana do int. (Możliwe, że o to ci chodziło, i źle cię zrozumiałem.) –

+0

@Tomalak: to tylko semantyka, czy niepodpisane 174 jest akurat podpisane -85, czy też było przepełnienie. Dla mnie przepełnienie ma więcej wspólnego z obliczeniami. W końcu wynik jest taki sam. – stefaanv

+0

@stefaanv: W porządku; nie o to mi chodziło. –

9

Brak wartości ujemnych ASCII. ASCII zawiera definicje dla 128 znaków. Ich indeksy są dodatnie (lub zero!).

Widzisz tę wartość ujemną, ponieważ znak jest z zestawu Rozszerzony ASCII i jest zbyt duży, aby zmieścić się w literał znaków. W związku z tym wartość przelewa się do bitu twojego char (prawdopodobnie podpisanego w systemie), który definiuje ujemność.

Rozwiązaniem jest napisać wartości bezpośrednio:

unsigned char a = 0xAE; // « 

Pisałem ją w zapisie szesnastkowym dla konwencji i dlatego myślę, że wygląda ładniej niż 174. :)

+1

Ich indeksy są nieujemne ;-). –

+0

@Charles: Pfft. : P –

+1

Nie ma czegoś takiego jak "Rozszerzony ASCII". –

2

Zakresy ASCII 0..127, ANSI (zwane również "rozszerzonymi ASCII") w zakresie 0..255.

Zakres ANSI nie mieści się w podpisanym znaku (domyślny typ dla znaków w większości kompilatorów).

Większość kompilatorów ma opcję taką jak "char" Typ jest niepodpisany (GCC).

+3

Podpisany znak nie jest "domyślnym typem znaków". Podpisanie niewykwalifikowanego typu "char" jest całkowicie określone przez implementację. Literały znaków mają typ 'char'. Jego system po prostu używa podpisanej implementacji dla 'char' (jak przypuszczam, jak większość popularnych systemów). –

+0

(Jest to przeciwieństwo 'int', które jest jawnie, zawsze takie samo jak' signed int'.) –

+0

Wyjaśnię to.Miałem na myśli "domyślne w większości kompilatorów", a nie specyfikację. – jv42

1

Posiadałem ten artefakt. Kiedy używasz char jako symboli, nie masz problemu. Ale kiedy używasz go jako liczby całkowitej (z isalpha() itd.), A kod ASCII jest większy niż 127, to "char" interpretowany jako 'signed char' i isalpha() zwraca wyjątek.Kiedy potrzebuję użyć "znaku" jako liczby całkowitej, rzutuję "znak" na niepodpisany:

  • isalpha ((unsigned char) my_char);

@ n0rd: koi8 kodowej używa ASCII od 128 do 255 i innych stron kodowych narodowych: http://www.asciitable.com/

0

w reprezentacji znaków, masz 8 bitów (1 bajt) przydzielone. Poza tym pierwszy bit jest używany do reprezentowania znaku. W przypadku znaku bez znaku używa on wszystkich 8 bitów do reprezentowania liczby od 0 do 255, gdzie 128-255 są nazywane rozszerzonymi ASCII. Ze względu na reprezentację w pamięci, jak opisałem, musimy -1 posiadające taką samą wartość jak 255, char(-2)==char(254)

Powiązane problemy