Czy zmienna typu Integer w C zajmuje 2 bajty czy 4 bajty? Od jakich czynników to zależy?
Większość podręczników mówi, że zmienne całkowite zajmują 2 bajty. Ale kiedy uruchamiam program wyświetlający kolejne adresy tablicy liczb całkowitych, pokazuje różnicę 4.
int
jest tylko jednym z kilku typów liczb całkowitych . Pytałeś o rozmiar „liczby całkowitej”; prawdopodobnie chciałeś zapytać o rozmiarint
.int
ma 2 bajty (a) prawdopodobnie odnosi się do starego systemu i (b) nie wyjaśnia, że rozmiar będzie się różnił w zależności od systemu. Najlepszą książką na temat C jest „Język programowania C” autorstwa Kernighana i Ritchiego, chociaż zakłada pewne doświadczenie w programowaniu. Zobacz również pytanie 18.10 w comp.lang.c FAQ .#define int int64_t
na platformie 64-bitowej, więc też nie. Po prostu użyjsizeof
. ;-)Odpowiedzi:
Wiem, że to jest równe
sizeof(int)
. Rozmiar plikuint
jest naprawdę zależny od kompilatora. Dawno temu, kiedy procesory były 16-bitowe, wartość anint
wynosiła 2 bajty. Obecnie jest to najczęściej 4 bajty w systemach 32-bitowych i 64-bitowych.Mimo
sizeof(int)
to użycie jest najlepszym sposobem uzyskania rozmiaru liczby całkowitej dla określonego systemu, w którym program jest wykonywany.EDYCJA: Naprawiono błędną instrukcję, która
int
ma 8 bajtów w większości systemów 64-bitowych. Na przykład jest to 4 bajty w 64-bitowym GCC.źródło
sizeof(int)
może mieć dowolną wartość z1
. Bajt nie musi mieć 8 bitów, a niektóre maszyny nie mają 8-bitowej adresowalnej jednostki (co w zasadzie jest definicją bajtu w standardzie). Odpowiedź nie jest poprawna bez dalszych informacji.Jest to jeden z punktów w C, który może być początkowo mylący, ale standard C określa tylko minimalny zakres dla typów całkowitych, które mają być obsługiwane.
int
gwarantuje, że będzie w stanie przechowywać od -32767 do 32767, co wymaga 16 bitów. W tym przypadkuint
, wynosi 2 bajty. Jednak implementacje mogą wykraczać poza to minimum, ponieważ zobaczysz, że wiele współczesnych kompilatorów tworzyint
32-bitowe (co również oznacza 4 bajty dość wszechobecne).Powodem, dla którego twoja książka podaje 2 bajty, jest najprawdopodobniej to, że jest stara. Kiedyś była to norma. Ogólnie rzecz biorąc, zawsze powinieneś używać
sizeof
operatora, jeśli chcesz dowiedzieć się, ile bajtów znajduje się na używanej platformie.Aby rozwiązać ten problem, C99 dodał nowe typy, w których można jawnie poprosić o określoną liczbę całkowitą, na przykład
int16_t
lubint32_t
. Wcześniej nie było uniwersalnego sposobu na uzyskanie liczby całkowitej o określonej szerokości (chociaż większość platform udostępniała podobne typy dla każdej platformy).źródło
int
. C nie przyjmuje takiego założenia. Systemy dopełnienia i wielkości znaku 1 nie mogą reprezentować-32768
16 bitów; raczej mają dwie reprezentacje dla zera (dodatnią i ujemną). Dlatego minimalny zasięgint
to[-32767..32767]
.Nie ma konkretnej odpowiedzi. To zależy od platformy. Jest zdefiniowany w ramach implementacji. Może to być 2, 4 lub coś innego.
Idea stojąca za
int
polegał na tym, że miał on odpowiadać naturalnemu rozmiarowi „słowa” na danej platformie: 16 bitów na platformach 16-bitowych, 32 bity na platformach 32-bitowych, 64 bity na platformach 64-bitowych, masz pomysł. Jednak ze względu na kompatybilność wsteczną niektóre kompilatory wolą trzymać się wersji 32-bitowej,int
nawet na platformach 64-bitowych.Czas 2-bajtowy
int
już dawno minął (platformy 16-bitowe?), Chyba że używasz jakiejś wbudowanej platformy z 16-bitowym rozmiarem słowa. Twoje podręczniki są prawdopodobnie bardzo stare.źródło
The idea behind int was that it was supposed to match the natural "word" size on the given platform
- To jest to, czego szukałem. Masz pojęcie, jaki może być powód? W wolnym świecie int może zajmować dowolną liczbę kolejnych bajtów w pamięci, prawda? 8, 16 cokolwiekOdpowiedź na to pytanie zależy od używanej platformy.
Ale niezależnie od platformy możesz niezawodnie założyć następujące typy:
źródło
To zależy od używanej platformy, a także od konfiguracji kompilatora. Jedyną miarodajną odpowiedzią jest użycie
sizeof
operatora, aby zobaczyć, jak duża jest liczba całkowita w konkretnej sytuacji.Najlepiej rozważyć zasięg , a nie rozmiar . Oba będą się różnić w praktyce, chociaż, jak zobaczymy, znacznie bardziej niezawodnym jest wybieranie typów zmiennych według zakresu niż rozmiaru. Należy również zauważyć, że standard zachęca nas do rozważenia wyboru typów liczb całkowitych na podstawie zakresu a nie rozmiar , ale na razie zignorujmy standardową praktykę i pozwól naszej ciekawości zbadać
sizeof
, bajty iCHAR_BIT
reprezentacje liczb całkowitych ... królicza nora i zobacz to na własne oczy ...sizeof
, bajty iCHAR_BIT
Poniższe stwierdzenie, zaczerpnięte ze standardu C (do którego link znajduje się powyżej), opisuje to słowami, których nie sądzę, aby można było poprawić.
Zakładając, że jasne zrozumienie doprowadzi nas do dyskusji na temat bajtów . W rzeczywistości przyjmuje się, że bajt to osiem bitów
CHAR_BIT
mówi ci, ile bitów jest w bajcie . To tylko kolejny z tych niuansów, których nie bierze się pod uwagę, gdy mówimy o typowych dwu- (lub czterobajtowych) liczbach całkowitych .Podsumujmy do tej pory:
sizeof
=> rozmiar w bajtach iCHAR_BIT
=> liczba bitów w bajcieTak więc, w zależności od systemu,
sizeof (unsigned int)
może to być dowolna wartość większa od zera (nie tylko 2 lub 4), jak gdyby wynosiłaCHAR_BIT
16, wtedy pojedynczy (szesnastobitowy) bajt ma wystarczającą liczbę bitów, aby reprezentować szesnastobitową liczbę całkowitą opisaną przez norm (cytowane poniżej). To niekoniecznie przydatne informacje, prawda? Zanurzmy się głębiej ...Reprezentacja liczb całkowitych
Ç Określono minimalne dokładności / zakres dla standardowych typów całkowitych (a
CHAR_BIT
, także FWIW) tutaj . Na tej podstawie możemy wyliczyć minimalną liczbę bitów potrzebnych do przechowywania wartości , ale równie dobrze możemy po prostu wybrać nasze zmienne na podstawie zakresów . Niemniej jednak ogromna część szczegółów wymaganych dla tej odpowiedzi znajduje się tutaj. Na przykład następujące, które standardunsigned int
wymaga (co najmniej) szesnastu bitów pamięci:W ten sposób widzimy, że
unsigned int
wymaga ( co najmniej ) 16 bitów , czyli tam, gdzie otrzymujesz dwa bajty (zakładając, żeCHAR_BIT
jest to 8) ... a później, gdy limit wzrósł do2³² - 1
, ludzie podawali zamiast tego 4 bajty. To wyjaśnia obserwowane przez Ciebie zjawiska:Używasz starożytnego podręcznika i kompilatora, który uczy cię nieprzenośnego języka C; autor, który napisał twój podręcznik, może nawet nie być tego świadomy
CHAR_BIT
. Ci powinni uaktualnić swój podręcznik (i kompilatora), i staramy się pamiętać, że to ciągle rozwijająca się dziedzina, że trzeba się zatrzymać przed konkurować ... dość o tym, choć; zobaczmy, jakie inne nieprzenośne sekrety leżą u podstaw bajtów całkowitych przechowują ...Wydaje się, że liczą się bity wartości . W powyższym przykładzie zastosowano plik
unsigned
całkowitego, który zazwyczaj zawiera tylko bity wartości, więc łatwo przeoczyć diabła w szczegółach.Sign bits ... W powyższym przykładzie zacytowałem
UINT_MAX
jako górną granicę,unsigned int
ponieważ jest to trywialny przykład wyodrębnienia wartości16
z komentarza. W przypadku typów ze znakiem, aby rozróżnić wartości dodatnie i ujemne (to jest znak), musimy również dołączyć bit znaku.Wypełnianie bitów ... Chociaż nie jest powszechne napotykanie komputerów, które mają dopełnianie bitów w liczbach całkowitych, standard C pozwala na to; niektóre maszyny (np. ta ) implementują większe typy liczb całkowitych, łącząc ze sobą dwie mniejsze (ze znakiem) wartości całkowite ... a kiedy łączysz liczby całkowite ze znakiem, otrzymujesz zmarnowany bit znaku. Ten zmarnowany bit jest uważany za wypełnienie w C. Inne przykłady bitów wypełnienia mogą obejmować bity parzystości i bity pułapki .
Jak widać, standard wydaje się zachęcać do rozważania zakresów, takich jak
INT_MIN
...INT_MAX
i innych wartości minimalnych / maksymalnych ze standardu przy wyborze typów całkowitych, i zniechęca do polegania na rozmiarach, ponieważ istnieją inne subtelne czynniki, które mogą zostać zapomniane, takie jakCHAR_BIT
i wypełnianie bitów, które może wpływać na wartośćsizeof (int)
(tj. powszechne nieporozumienia dotyczące dwu- i czterobajtowych liczb całkowitych pomijają te szczegóły).źródło
Projekt standardowy C99 N1256
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
Rozmiar
int
i wszystkie inne typy liczb całkowitych są zdefiniowane w implementacji, C99 określa tylko:5.2.4.2.1 „Rozmiary typów całkowitych
<limits.h>
” podaje minimalne rozmiary:6.2.5 „Typy” mówi wtedy:
oraz 6.3.1.1 „Boolean, znaki i liczby całkowite” określa względne stopnie konwersji:
źródło
Jedyne gwarancje to, że
char
musi mieć co najmniej 8 bitów szerokościshort
iint
musi mieć co najmniej 16 bitów szerokości ilong
musi mieć co najmniej 32 bity szerokości oraz żesizeof (char)
<=sizeof (short)
<=sizeof (int)
<=sizeof (long)
(to samo dotyczy wersji bez znaku tych typów ).int
może mieć szerokość od 16 do 64 bitów w zależności od platformy.źródło
Odpowiedź brzmi „tak” / „nie” / „może” / „może nie”.
Język programowania C określa, co następuje: najmniejsza adresowalna jednostka, znana
char
i nazywana „bajtem” , ma dokładnieCHAR_BIT
szerokość bitów, gdzieCHAR_BIT
wynosi co najmniej 8.Zatem jeden bajt w C niekoniecznie jest oktetem , czyli 8 bitów. W przeszłości jedna z pierwszych platform do uruchamiania kodu C (i Unix) miała 4-bajtowe
int
- ale w sumieint
miała 36 bitów, ponieważCHAR_BIT
było ich 9!int
ma być naturalną liczbą całkowitą dla platformy, która ma zakres co najmniej-32767 ... 32767
. Możesz uzyskać rozmiarint
w bajtach platformy za pomocąsizeof(int)
; kiedy pomnożymy tę wartość przezCHAR_BIT
, będziecie wiedzieć, jak szeroka jest ona w bitach.Podczas gdy maszyny 36-bitowe są w większości martwe, nadal istnieją platformy z bajtami innymi niż 8-bitowe. Jeszcze wczoraj pojawiło się pytanie o mikrokontroler Texas Instruments z 16-bitowymi bajtami , który ma kompilator zgodny z C99, C11.
Na TMS320C28x wydaje się, że
char
,short
iint
są wszystkie 16 bitów szerokości, a więc jednego bajta.long int
to 2 bajty ilong long int
4 bajty. Piękno C polega na tym, że wciąż można napisać wydajny program dla takiej platformy, a nawet zrobić to w sposób przenośny!źródło
W większości zależy to od używanej platformy, od kompilatora do kompilatora, obecnie w większości kompilatorów int ma 4 bajty . Jeśli chcesz sprawdzić, czego używa Twój kompilator, możesz użyć
sizeof(int)
.Jedyną obietnicą kompilatora c jest to, że rozmiar short musi być równy lub mniejszy niż int, a rozmiar long musi być równy lub większy niż int. Więc jeśli rozmiar int wynosi 4, to rozmiar short może wynosić 2 lub 4, ale nie większy niż to. To samo jest prawdziwe dla długich i int. Mówi się również, że rozmiar krótki i długi nie mogą być takie same.
źródło
%d
przezsize_t
parametr jest UB.Zależy to od implementacji, ale zwykle na x86 i innych popularnych architekturach, takich jak ARM,
int
zajmuje 4 bajty. Zawsze możesz to sprawdzić w czasie kompilacji, używającsizeof(int)
lub dowolnego innego typu, który chcesz sprawdzić.Jeśli chcesz mieć pewność, że używasz typu o określonym rozmiarze, użyj typów w
<stdint.h>
źródło
Zwraca 4, ale prawdopodobnie zależy od komputera.
źródło
C pozwala, aby „bajty” były czymś innym niż 8 bitów na „bajt”.
Wartość wyższa niż 8 jest coraz rzadsza. Aby zapewnić maksymalną przenośność, użyj
CHAR_BIT
zamiast 8. Rozmiarint
w bitach w C wynosisizeof(int) * CHAR_BIT
.Rozmiar
int
bitu to zwykle 32 lub 16 bitów. C określone minimalne zakresy :Minimalny zakres dla
int
sił Wielkość bitowa być co najmniej 16 - nawet w przypadku, gdy procesor jest „8-bitowa”. Rozmiar podobny do 64 bitów występuje w wyspecjalizowanych procesorach. Inne wartości, takie jak 18, 24, 36 itd., Wystąpiły na platformach historycznych lub są przynajmniej teoretycznie możliwe. Współczesne kodowanie rzadko martwi się oint
rozmiary bitów inne niż potęga 2 .Procesor i architektura komputera decydują o
int
wyborze rozmiaru bitu.Jednak nawet w przypadku procesorów 64-bitowych
int
rozmiar kompilatora może być 32-bitowy ze względu na kompatybilność, ponieważ duże bazy kodu zależą odint
32-bitowego (lub 32/16).źródło
To jest dobre źródło odpowiedzi na to pytanie.
Ale to pytanie jest zawsze prawdziwą odpowiedzią „Tak. Obie”.
To zależy od Twojej architektury. Jeśli zamierzasz pracować na komputerze 16-bitowym lub mniejszym, nie może to być 4 bajty (= 32 bity). Jeśli pracujesz na komputerze 32-bitowym lub lepszym, jego długość wynosi 32-bit.
Aby to zrozumieć, przygotuj program do wypisywania czegoś czytelnego i użyj funkcji „sizeof”. To zwraca rozmiar w bajtach zadeklarowanego typu danych. Ale bądź ostrożny, używając tego z tablicami.
Jeśli deklarujesz
int t[12];
, zwróci to 12 * 4 bajty. Aby uzyskać długość tej tablicy, po prostu użyjsizeof(t)/sizeof(t[0])
. Jeśli masz zamiar zbudować funkcję, która powinna obliczyć rozmiar tablicy wysyłania, pamiętaj, że ifWięc to nawet nie zwróci czegoś innego. Jeśli zdefiniujesz tablicę i później spróbujesz uzyskać długość, użyj sizeof. Jeśli wysyłasz tablicę do funkcji, pamiętaj, że wysyłana wartość jest tylko wskaźnikiem na pierwszym elemencie. Ale w pierwszym przypadku zawsze wiesz, jaki rozmiar ma twoja tablica. Przypadek drugi można zrozumieć, definiując dwie funkcje i tracić pewną wydajność. Zdefiniuj funkcję (tablica t) i zdefiniuj funkcję2 (tablica t, int size_of_t). Wywołaj "function (t)", zmierz długość za pomocą jakiegoś kopiowania i wyślij wynik do function2, gdzie możesz zrobić, co chcesz, na zmiennych rozmiarach tablic.
źródło
char
Jest zawszesigned
)