2016-06-03 23 views
7

W CJaki jest domyślny typ danych liczbowych w C?

unsigned int size = 1024*1024*1024*2; 

co powoduje ostrzeżenie "całkowitą przepełnienie ekspresji ..." While

unsigned int size = 2147483648; 

wyniki bez ostrzeżenia?

Czy prawidłowa wartość pierwszego wyrażenia jest domyślna jako int? Gdzie to wspomina w specyfikacji C99?

+1

Czy na pewno druga wartość nie jest ["2147483648"] (https://www.google.co.in/search?q=1024*1024*1024*2&rlz=1C1GIGM_enIN617IN617&oq=1024*1024*1024*2&aqs = chrome..69i57.1172j0j7 & sourceid = chrome & ie = UTF-8)? –

+0

Prawdopodobnie miałeś na myśli wartość '2147483648'. Moja odpowiedź zakłada to. – 2501

+0

Naprawiono błąd! Dzięki! – mingpepe

Odpowiedz

9

Przy użyciu stałej dziesiętny bez przyrostków typ stałej dziesiętnych jest pierwszym, który może być reprezentowany w kolejności (obecny standard C 6.4.4 Stałe P5)

  • Int
  • długo Int
  • dawno Int

typu pierwszego słowa jest int, ponieważ każdy stałe o wartości 1024 i 2 mogą być reprezentowane int. Obliczenie tych stałych zostanie wykonane w typie int, a wynik zostanie przepełniony.

Zakładając, że INT_MAX jest równy 2147483647, a LONG_MAX jest większy niż 2147483647, typ drugiego wyrażenia to long int, ponieważ ta wartość nie może być reprezentowana jako int, ale może być tak długa. Jeśli INT_MAX jest równy LONG_MAX jest równy 2147483647, wówczas typem jest long long int.

+1

O ile INT_MAX == LONG_MAX, w takim przypadku drugie wyrażenie jest prawdopodobnie typu' long long int'. Zwróć uwagę, że Win64 to środowisko 64-bitowe, w którym INT_MAX == LONG_MAX; większość 32-bitowych środowisk działa z INT_MAX == LONG_MAX. –

+0

@ JonathanLeffler Dziękuję. Tak, to są wspólne ograniczenia, powinienem był o tym pamiętać. – 2501

3
unsigned int size = 1024*1024*1024*2; 

To wyrażenie 1024*1024*1024*2 (w wyrażeniu 1024 i 2 są typu signed int) daje wynik, który jest typu signed int i wartość ta jest zbyt duża dla signed int. Dlatego otrzymujesz ostrzeżenie.

Po tym podpisanym mnożeniu jest ono przypisywane do unsigned int.

+0

Wiem, że wartość jest przepełnieniem dla podpisanego int. Ale dlaczego jest podpisany int? – mingpepe

+1

@mingpepe Ponieważ domyślnie '1024' i' 2' są liczbami całkowitymi ze znakiem, więc wynik mnożenia jest również typu 'signed int', a następnie typ jest zmieniany, gdy jest przypisany do' unsigned int'. – ameyCU

+0

Przepełnienie produktu '1024 * 1024 * 1024 * 2' i przepełnienie' int' to UB. Lepiej używać '1024u * 1024 * 1024 * 2' – chux