2008-09-14 28 views
8

Jeśli mam:C porównanie wartości zmiennej i stałej nie pasujące

signed char * p; 

i robię porównania:

if (*p == 0xFF) 
    break; 

nigdy nie złapać 0xFF, ale jeśli mogę zastąpić go -1 to będzie:

if (*p == (signed char)0xFF) 
    break; 

Jak to się dzieje? Czy to jest coś z flagą ze znakiem? I choć to 0xFF == -1 == 255.

Odpowiedz

29

Wartość 0xFF jest podpisaną wartością int. C będzie promować *p do int robiąc porównanie, więc pierwsza instrukcja if jest równoznaczne z:

if(-1 == 255) break; 

co jest oczywiście fałszywe. Dzięki zastosowaniu (signed char)0xFF stwierdzenie jest równoznaczne z:

if(-1 == -1) break; 

który działa zgodnie z oczekiwaniami. Kluczową kwestią jest tutaj porównanie typów z typami int zamiast signed char.

+0

0xFF jest podpisane, nie podpisany. 0xFFU to niepodpisana wersja. Tylko * p musi być promowany. – Niall

+0

Niall: Masz całkowitą rację; Zaktualizuję odpowiedź. –

2

To rzuca na int dla pierwszego stosunku od 0xFF jest nadal uważane int, czyli swoją postać jest -128 do 127, ale wciąż jest 0xFF 255.

W drugim przypadku podasz że 0xFF jest rzeczywiście znakiem char, a nie int

4

Liczby całkowite mają podpis typu int. Ponieważ 0xFF jest int podpisane, kompilator konwertuje * p na podpisane int, a następnie robi porównanie.

Gdy * p wynosi -1, który jest następnie konwertowany z podpisanego znaku na podpisany int, to nadal -1 ma reprezentację 0xFFFFFFFF, która nie jest równa 0xFF.

1

0xff będzie widziane jako stała liczbowa o wartości 255. Należy zawsze zwracać uwagę na takie porównanie różnych typów. Jeśli chcesz mieć pewność, że kompilator wygeneruje właściwy kod, należy użyć typecast:

 
if(*p == (signed char)0xFF) break; 

Zresztą uważaj że następne oświadczenie woli nie działają tak samo:

 
if((int)*p == 0xFF) break; 

Ponadto, może byłoby lepszym pomysłem, aby uniknąć znaki podpisane, lub, że trzeba użyć podpisane znaków i porównać je z wartościami takimi jak podpisanych -1 w tym przypadku:

 
if(*p == -1) break; 

0xFF == - 1 tylko wtedy, gdy te wartości zostaną przypisane do jakiegoś char (lub unsigned char) zmienne:

 
char a=0xff; 
char b=-1; 
if(a==b) break; 
Powiązane problemy