Mam problemy ze zrozumieniem, jakie były dokładne cele tworzenia short
, int
i long
typy danych w C?
Powód, o który pytam, nie wygląda na to, że ich rozmiary są ograniczone - mogą mieć dowolny rozmiar, o ile na przykład short
jest mniejszy niż jeden int
.
W jakich sytuacjach powinieneś użyć unsigned int
lub unsigned long
, na przykład, zamiast a size_t
, gdy nie daje to żadnej nadziei na zgodność binarną?
(Jeśli nie znasz rozmiaru, to skąd wiesz, kiedy wybrać, który?)
c
data-types
użytkownik541686
źródło
źródło
<stdint.h>
sizeof(short) == 2 * sizeof(char)
lub podobni?sizeof(char) == sizeof(short)
ma to sens. Niestety nie ma sposobu na określenie liczb całkowitych w taki sposób, aby pasowały one do wszystkich możliwych i istniejących platform.Odpowiedzi:
Będzie to określone przez architekturę, której używasz. Na układzie Zilog z80 (wspólny układ osadzony) byłyby jednego rozmiaru, podczas gdy na chipsecie x86 mogłyby mieć zupełnie inny rozmiar. Jednak same rozmiary są względem siebie ustalonymi proporcjami. Zasadniczo krótkie i długie nie są typami, ale kwalifikują się do typu int. Krótkie ints będą o jeden rząd wielkości mniejsze niż (zwykłe) int, a long ints będą o rząd wielkości wyższe. Powiedzmy, że twoja Int jest ograniczona do 4 bajtów, krótki kwalifikator ogranicza ją do 4 bajtów, chociaż 2 bajty są również bardzo częste, a długi kwalifikator zwiększa ją potencjalnie do 8 bajtów, chociaż może być mniejszy do 4 bajtów. Należy pamiętać, że zależy to również od długości słowa, więc w systemie 32-bitowym i tak możesz uzyskać maksymalnie 4 bajty na int, co daje tyle samo co zwykłe int. Zatem Short ≤ Int ≤ Long.
Jeśli jednak wydłużysz go ponownie, możesz wcisnąć int do następnej komórki, co daje 8 całych bajtów pamięci. Jest to rozmiar słowa dla maszyn 64-bitowych, więc nie muszą się one martwić o takie rzeczy i po prostu używają jednej komórki dla długich liczb całkowitych, co pozwala im być kolejną kolejnością powyżej standardowych liczb wewnętrznych, podczas gdy długie długie cyfry stają się naprawdę bitowe.
Jeśli chodzi o wybór, sprowadza się do czegoś, na co programiści Java nie muszą się martwić. „Jaka jest twoja architektura?” Ponieważ wszystko zależy od wielkości słowa pamięci danego urządzenia, musisz zrozumieć to z góry, zanim zdecydujesz, którego użyć. Następnie wybierasz najmniejszy rozsądny rozmiar, aby zaoszczędzić jak najwięcej pamięci, ponieważ pamięć ta zostanie przydzielona niezależnie od tego, czy użyjesz wszystkich bitów, czy nie. Więc oszczędzasz, gdzie możesz i wybierasz szorty, kiedy możesz, i ints, kiedy nie możesz i jeśli potrzebujesz czegoś większego niż to, co dajesz zwykłym intymnym; wydłużysz w razie potrzeby, dopóki nie uderzysz w słowo sufit. Następnie musisz podać procedury dużej liczby lub pobrać je z biblioteki.
C może być „przenośnym zestawem”, ale nadal musisz znać swój sprzęt.
źródło
Chociaż dzisiaj „bajt” oznacza „8 bitów”, nie zawsze tak było. Maszyny wykorzystały adresowalne fragmenty 4 bitów, 8 bitów, 12 bitów, 16 bitów, 32 bitów i 36 bitów (i prawdopodobnie także inne rozmiary). Jednym z założeń projektowych C było zastosowanie na maszynach o różnych rozmiarach i konfiguracjach pamięci.
Myślę, że pierwotnie zamierzeniem projektu było, aby każdy typ
int
był najmniejszą rzeczą, która mogła poradzić sobie z liczbami o różnych rozmiarach, i żeint
byłby to najbardziej praktyczny rozmiar „ogólnego zastosowania”, który mógłby obsłużyć +/- 32767. Nie wydaje mi się, aby istniała chęć lub zamiar stworzenia języka, który byłby nadal używany, gdy komputery stały się tak potężne, że operacje na liczbach 64-bitowych kosztują tyle samo, co operacje na mniejszych.Największy problem z semantyką typu całkowitoliczbowego C polega na tym, że w niektórych kontekstach reprezentują one liczby kardynalne lub liczby całkowite matematyczne, podczas gdy w innych kontekstach są używane do reprezentowania członków otulającego abstrakcyjnego algebraicznego pierścienia liczb całkowitych przystających mod 2 ^ n [np. Odejmowanie maksymalna reprezentowalna wartość od 0 jest określona, aby dać 1], ale zachowania są określone bardziej na podstawie tego, co wydawały się robić kompilatory w czasach, gdy rozmiary słów komputerowych wynosiły około 16 bitów (a rozmiar słów 36-bitowych byłby ogromny ), a nie na podstawie tego, co ma sens na komputerze 64-bitowym. W konsekwencji wynik odejmowania 32-bitowej wartości bez znaku od mniejszej 32-bitowej wartości bez znaku może być dużą 32-bitową wartością bez znaku lub ujemną liczbą 64-bitową.
źródło
/programming/589575/size-of-int-long-etc
Tak więc w najczęściej używanych architekturach char to 1 bajt, short i int to co najmniej 2 bajty, a long to co najmniej 4 bajty.
I intencją jest, aby „int” był najbardziej naturalną / normalną / wydajną reprezentacją dla bieżącego procesora.
Zatem ogólną zasadą jest używanie „int”, chyba że twoje wartości przekraczają +/- 32K, co powoduje, że (na starszych procesorach) używasz „długiego”. ... lub chyba, że tworzysz duże tablice małych (<32 KB) wartości, a pamięć stanowi problem - więc użyjesz „krótkiego”, aby zaoszczędzić pamięć (a może „char” lub „byte”).
źródło
int
rzadko jest dobrym wyborem, prawda? I tak prawie zawsze używamsize_t
(a nawetptrdiff_t
!), Aby uniknąć problemów z kodowaniem.C został zaprojektowany, aby aktywnie radzić sobie z pamięcią na różnych poziomach. Są przypadki, w których różnica między skrótem, intem i długością oraz pomiędzy zmiennoprzecinkowym i podwójnym ma znaczenie ze względu na ograniczenia pamięci, architekturę itp. Mimo że teraz nie ma to większego znaczenia, nadal istnieją środowiska, w których to robi (np. Osadzone i w przypadki, w których dane są ogromne), a przejście z głównie architektur 32-bitowych na 64-bitowe sprawia, że znów stanowi to problem. (Za dziesięć lub dwadzieścia lat, kiedy przejdziemy do architektur 128-bitowych, a C / C ++ jest nadal popularny, znowu będzie to problemem). Masz jednak rację, że binarna kompatybilność cierpi, dlatego nie chcesz używać tych rozmiarów zmiennych, jeśli to ma znaczenie.
Zapytałeś, skąd wiesz, którego użyć, jeśli nie znasz rozmiaru, ale znasz rozmiar danej kombinacji architektury / kompilatora, a jeśli chcesz zoptymalizować pamięć na tym poziomie, lepiej go poznaj. Nie możesz zoptymalizować tego po prostu na różnych platformach, ponieważ nie znasz ich rozmiarów, więc nie chcesz używać tych funkcji do tego celu. Ale wiele rzeczy napisanych w C jest specyficznych dla platformy, co pomimo mody na „cross platform”, pozwala na pewne korzystne optymalizacje.
źródło