2012-03-04 17 views
6

W poniższym kodzie:typ danych promocja w C

#include "stdio.h" 
signed char a= 0x80; 
unsigned char b= 0x01; 


void main (void) 
{ 
    if(b*a>1) 
     printf("promoted\n"); 
    else if (b*a<1) 
     printf("why doesnt promotion work?"); 

    while(1); 
} 

się spodziewałem „promowane” do wydrukowania Ale to nie robi Dlaczego Jeśli mogę się datatypes podpisanych i unsigned int i mają jak..? liczbą ujemną, np 0x80000000 i b jako liczbę dodatnią, 0x01 „promowane” zostanie wydrukowane zgodnie z oczekiwaniami.

PLZ pomóż mi zrozumieć czym jest problem!

Odpowiedz

10

właśnie został złapany przez niechlujny zasady promocji gatunku C.

W języku C półprodukty typu integralnego mniejsze niż int są automatycznie promowane do int.

Więc trzeba:

0x80 * 0x01 = -128 * 1 

0x80 zostanie podpisany rozszerzony wpisać int:

0xffffff80 * 0x00000001 = -128 * 1 = -128 

Więc wynik jest -128 a tym samym jest mniej niż 1.


Podczas korzystania typ int i unsigned int oba operandy awansować do unsigned int. 0x80000000 * 0x01 = 0x80000000 jako liczba całkowita bez znaku jest większa niż 1.


Więc tutaj jest porównanie side-by-side z promocji typu, który zabiera miejsce:

(signed char) * (unsigned char) -> int 
(signed int) * (unsigned int) -> unsigned int 

(signed char)0x80  * (unsigned char)0x01 -> (int)   0xffffff80 
(signed int)0x80000000 * (unsigned int)0x01 -> (unsigned int)0x80000000 

(int)   0xffffff80 is negative -> prints "why doesnt promotion work?" 
(unsigned int)0x80000000 is positive -> prints "promoted" 

Here's a reference to the type-promotion rules of C.

+0

@Mystical Nie rozumiem twojej odpowiedzi. Nawet jeśli zostanie podpisany rozszerzony na typ int, co nie wydaje mi się, że to robi, ale zakładając, że tak jest, dlaczego nie jest promowany do unsigned int, a produkt jest liczbą + ve? – Dom045

+0

+1 - Ta odpowiedź jest znacznie lepsza/ważniejsza niż moja przez długą milę (więc ją usunąłem) –

+0

@ Dom045 Ponieważ specyfikacja mówi tak. Zarówno 'signed char' i' unsigned char' są niższymi typami niż 'int'. Więc oboje zostaną awansowani do "int". W przypadku 'signed int' vs.' unsigned int' standard podaje, że oba są konwertowane na 'unsigned int'. Reguły można znaleźć tutaj: https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules – Mysticial

2

Powodem printf("promoted\n"); nigdy biegnie dlatego b*a jest zawsze == -128 , który jest mniejszy niż 1

a  b  
0x80 * 0x01 = -128 * 1