Różnica między int32, int, int32_t, int8 i int8_t

104

int32_tNiedawno natknąłem się na typ danych w programie C. Wiem, że przechowuje 32 bity, ale czy nie inti int32robi to samo?

Chcę też używać charw programie. Czy mogę int8_tzamiast tego użyć ? Jaka jest różnica?

Podsumowując: jaka jest różnica między int32, int, int32_t, int8 i int8_t w C?

linuxfreak
źródło

Odpowiedzi:

122

Pomiędzy int32a int32_t(i podobnie między int8i int8_t) różnica jest dość prosta: standard C definiuje int8_ti int32_t, ale nie definiuje niczego nazwanego int8lub int32- to drugie (jeśli w ogóle istnieją) pochodzi prawdopodobnie z innego nagłówka lub biblioteki (najprawdopodobniej poprzedza dodanie int8_ti int32_tw C99).

Zwykły intróżni się nieco od pozostałych. Gdzie int8_ti int32_tkażdy ma określony rozmiar, intmoże mieć dowolny rozmiar> = 16 bitów. W różnych czasach zarówno 16 bitów, jak i 32 bity były dość powszechne (aw przypadku implementacji 64-bitowej powinno to być prawdopodobnie 64 bity).

Z drugiej strony intgwarantuje się obecność w każdej implementacji języka C, gdzie int8_ti int32_tnie ma. Prawdopodobnie pozostaje pytanie, czy to ma dla Ciebie znaczenie. Jeśli używasz C na małych systemach wbudowanych i / lub starszych kompilatorach, może to być problem. Jeśli używasz go głównie z nowoczesnym kompilatorem na komputerach stacjonarnych / serwerach, prawdopodobnie nie będzie.

Ups - przegapiłem część dotyczącą char. Używałbyś int8_tzamiast znaku char, jeśli (i tylko wtedy) chcesz, aby typ liczby całkowitej gwarantowany miał dokładnie 8 bitów. Jeśli chcesz przechowywać znaki, prawdopodobnie będziesz chciał użyć charzamiast tego. Jego rozmiar może się różnić (pod względem liczby bitów), ale gwarantuje, że będzie to dokładnie jeden bajt. Jedna drobna dziwność: nie ma gwarancji, czy zwykły charjest podpisany, czy nie (a wiele kompilatorów może to zrobić, w zależności od flagi czasu kompilacji). Jeśli chcesz upewnić się, że jest podpisany lub niepodpisany, musisz to wyraźnie określić.

Jerry Coffin
źródło
1
@linuxfreak: Nie jestem pewien bool_t- nigdy wcześniej o tym nie słyszałem. Standard C definiuje _Booljako typ wbudowany. booljest definiowany tylko wtedy, gdy ty #include <stdbool.h>(jako makro, które rozwija się do _Bool).
Jerry Coffin
5
Powiedziałeś "dla implementacji 64-bitowej, (int) powinno prawdopodobnie mieć 64 bity". W praktyce int jest 32-bitowy na wszystkich popularnych platformach 64-bitowych, w tym Windows, Mac OS X, Linux i różnych odmianach systemu UNIX. Jedynym wyjątkiem są Cray / UNICOS, które obecnie wyszły z mody.
Sam Watkins
6
@SamWatkins: Tak, dlatego dokładnie powiedziałem „powinno być”, a nie „jest”. Standard mówi, że jest to „naturalny rozmiar sugerowany przez architekturę”, co (IMO) oznacza, że ​​na 64-bitowym procesorze naprawdę powinno to być 64 bity (chociaż, na dobre i na złe, masz całkowitą rację, że zwykle tak nie jest t). Z bardziej praktycznego punktu widzenia, to jest strasznie przydatny do typu 32-bitową wśród typów w C89, a jeśli int wynosi 64 bitów, długo musi wynosić co najmniej 64 bity też tak, że często tam być 32-bitowy rodzaj.
Jerry Coffin
2
@barlop: Tak. (Zarówno C, jak i C ++ narzucają minimalny zakres 255 wartości znaku, więc wymaga co najmniej 8 bitów, ale może być więcej).
Jerry Coffin
2
Zawsze miałem wrażenie, że jeden bajt ma dokładnie 8 bitów, a nie od 8 bitów wzwyż
ErlVolton
18

Typy danych _t to typedef w nagłówku stdint.h, podczas gdy int to wbudowany podstawowy typ danych. Dzięki temu _t będzie dostępne tylko wtedy, gdy istnieje stdint.h. int z drugiej strony jest gwarantowane.

Nadczłowiek
źródło
1
Dlaczego miałoby się używać _t?
Deven
@Deven Aby uniknąć sytuacji, w której kod działa gdzieś, ale nie gdzie indziej.
Franklin Yu
2

Zawsze pamiętaj, że „rozmiar” jest zmienny, jeśli nie zostanie wyraźnie określony, więc jeśli deklarujesz

 int i = 10;

W niektórych systemach może to dać 16-bitową liczbę całkowitą przez kompilator, a na innych może dać 32-bitową liczbę całkowitą (lub 64-bitową liczbę całkowitą w nowszych systemach).

W środowiskach osadzonych może to skończyć się dziwnymi wynikami (szczególnie podczas obsługi operacji we / wy mapowanych w pamięci lub może być rozważane jako prosta sytuacja tablicowa), dlatego zdecydowanie zaleca się określenie zmiennych o stałym rozmiarze. W starszych systemach możesz się spotkać

 typedef short INT16;
 typedef int INT32;
 typedef long INT64; 

Począwszy od C99, projektanci dodali plik nagłówkowy stdint.h, który zasadniczo wykorzystuje podobne typy plików.

W systemie Windows wpisy w pliku nagłówkowym stdin.h mogą być widoczne jako

 typedef signed char       int8_t;
 typedef signed short      int16_t;
 typedef signed int        int32_t;
 typedef unsigned char     uint8_t;

Jest coś więcej, jak liczby całkowite o minimalnej szerokości lub typy całkowitoliczbowe o dokładnej szerokości, myślę, że nie jest źle zbadać stdint.h dla lepszego zrozumienia.

Naumann
źródło
1
Twój kod zawiera literówkę: typedef short INT16;nie typedefs short INT16.
Galaxy,