niepodpisana liczba całkowita a rozmiar t

Zauważam, że współczesny kod C i c++ wydaje się używać size_t zamiast int/unsigned int praktycznie wszędzie - od parametrów dla funkcji ciągów C po STL. Jestem ciekaw powodu tego i korzyści, jakie to niesie.

 441
Author: Rob, 2008-09-25

8 answers

Typ size_t jest typem unsigned integer, który jest wynikiem operatora sizeof (i operatora offsetof), więc gwarantuje, że będzie wystarczająco duży, aby pomieścić rozmiar największego obiektu, który system może obsłużyć (np. statyczna tablica 8GB).

Typ size_t może być większy, równy lub mniejszy od unsigned int, a Twój kompilator może przyjąć założenia na ten temat w celu optymalizacji.

Dokładniejsze informacje można znaleźć w normie C99, sekcja 7.17, projekt który jest dostępny w Internecie w formacie pdf lub w standardzie C11, sekcja 7.19, dostępny również jako PDF draft .
 354
Author: Remo.D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-24 16:40:56

Klasyczny C (wczesny dialekt C opisany przez Briana Kernighana i Dennisa Ritchie ' ego w języku programowania C, Prentice-Hall, 1978) nie zawierał size_t. C standards Committee wprowadził size_t, aby wyeliminować problem przenośności

Wyjaśnione szczegółowo na embedded.com (z bardzo dobrym przykładem)

 89
Author: azeemarif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 20:52:47

W skrócie, size_t nigdy nie jest ujemny i maksymalizuje wydajność, ponieważ jest typedef ' D to być unsigned integer typ, który jest wystarczająco duży , ale nie zbyt duży, aby reprezentować rozmiar największego możliwego obiektu na docelowej platformie.

Rozmiary nigdy nie powinny być ujemne i rzeczywiście size_t jest typem niepodpisanym. Ponadto, ponieważ size_t jest niepodpisane, można przechowywać liczby, które są mniej więcej dwa razy większe niż w odpowiednim typie signed, ponieważ możemy użyć bitu znaku do reprezentowania magnitude, podobnie jak wszystkie pozostałe bity w unsigned integer. Gdy zyskamy jeszcze jeden bit, mnożemy zakres liczb, który możemy reprezentować przez współczynnik około dwóch.

Więc pytasz, dlaczego po prostu nie użyć unsigned int? Może nie być w stanie utrzymać wystarczająco dużych liczb. W implementacji, w której unsigned int ma 32 bity, największą liczbą, jaką może reprezentować, jest 4294967295. Niektóre procesory, takie jak IP16L32, mogą kopiować obiekty większe niż 4294967295 bajty.

Więc pytasz, dlaczego nie użyć unsigned long int? Informatyka pobiera opłaty za wydajność na niektórych platformach. Standard C wymaga, aby long zajmował co najmniej 32 bity. Platforma IP16L32 implementuje każdy 32-bitowy długi jako parę 16-bitowych słów. Prawie wszystkie 32-bitowe operatory na tych platformach wymagają dwóch instrukcji, jeśli nie więcej, ponieważ działają z 32 bitami w dwóch 16-bitowych kawałkach. Na przykład przesunięcie długości 32-bitowej zwykle wymaga dwóch instrukcji maszynowych - po jednej do przesunięcia każdego 16-bitowego fragmentu.

Użycie size_t pozwala uniknąć tej opłaty za wydajność. Według Ten fantastyczny artykuł , "Type size_t to typedef, który jest aliasem dla jakiegoś niepodpisanego typu integer, zazwyczaj unsigned int lub unsigned long, ale być może nawet unsigned long long. Każda Standardowa implementacja C powinna wybrać unsigned integer, który jest wystarczająco duży-ale nie większy niż jest potrzebny-aby reprezentować rozmiar największego możliwego obiektu na docelowej platformie."

 59
Author: Rose Perrone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 20:52:05

Typ size_t jest typem zwracanym przez operatora sizeof. Jest to niepodpisana liczba całkowita zdolna do wyrażenia rozmiaru w bajtach dowolnego zakresu pamięci obsługiwanego na maszynie hosta. Jest to (zazwyczaj) związane z ptrdiff_t, ponieważ ptrdiff_t jest podpisaną wartością całkowitą, taką, że sizeof (ptrdiff_t) i sizeof (size_t) są równe.

Podczas pisania kodu w C należy Zawsze używać size_t, gdy mamy do czynienia z zakresami pamięci.

Typ int z drugiej strony jest zasadniczo zdefiniowany jako rozmiar (podpisanej) wartości całkowitej, której maszyna hosta może użyć do najefektywniejszego wykonywania arytmetyki całkowitej. Na przykład, na wielu starszych komputerach typu PC wartość sizeof (size_t) będzie wynosić 4 (bajty), natomiast sizeof(int) będzie wynosić 2 (bajty). Arytmetyka 16-bitowa była szybsza niż arytmetyka 32-bitowa, chociaż procesor mógł obsługiwać (logiczną) przestrzeń pamięci do 4 GiB.

Używaj typu int tylko wtedy, gdy zależy ci na wydajności, ponieważ jego rzeczywista precyzja zależy w dużej mierze od obu opcji kompilatora i architektury maszyn. W szczególności standard C określa następujące niezmienniki: sizeof (char)

Uwaga: nie jest to to samo, co w Javie (które w rzeczywistości określa dokładność bitów dla każdego z typów 'char', 'byte', 'short', ' int ' i 'long').

 48
Author: Kevin S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 07:31:28

Typ size_t musi być wystarczająco duży, aby zapisać rozmiar dowolnego możliwego obiektu. Niepodpisana liczba całkowita nie musi spełniać tego warunku.

Na przykład w systemach 64-bitowych int i unsigned int mogą mieć szerokość 32-bitową, ale size_t musi być wystarczająco duży, aby przechowywać liczby większe niż 4G

 23
Author: Maciej Hehl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 07:08:27

Ten fragment podręcznika glibc 0.02 może być również istotny podczas badania tematu:

Istnieje potencjalny problem z typem size_t i wersjami GCC przed wydaniem 2.4. ANSI C wymaga, aby size_t zawsze był typem niepodpisanym. Dla kompatybilności z istniejącymi plikami nagłówkowymi systemów, GCC definiuje size_t w stddef.h' to be whatever type the system's sys / types.H ' definiuje to jako. Większość systemów uniksowych, które definiują size_t w `sys / types.H', zdefiniuj go jako typ podpisany. Jakiś kod w bibliotece zależy od size_t jest typem niepodpisanym i nie będzie działał poprawnie, jeśli jest podpisany.

Kod biblioteki GNU C, który oczekuje, że size_t będzie niepodpisany, jest poprawny. Definicja size_t jako typu podpisanego jest niepoprawna. Planujemy, że w wersji 2.4 GCC zawsze zdefiniuje size_t jako typ niepodpisany, a fixincludes' script will massage the system'ssys / types.żeby z tym nie kolidować.

W międzyczasie rozwiązujemy ten problem, nakazując GCC jawnie używać niepodpisanego typu dla size_t podczas kompilacji biblioteki GNU C. `configure ' automatycznie wykryje, jakiego typu GCC używa dla size_t arrange, aby zastąpić go w razie potrzeby.

 3
Author: Graeme Burke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-24 02:44:37

Jeśli mój kompilator jest ustawiony na 32 bit, size_t jest niczym innym jak typedef dla unsigned int. Jeśli mój kompilator jest ustawiony na 64 bit, size_t jest niczym innym jak typedef dla unsigned long long.

 1
Author: Zebrafish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 20:49:33

Size_t jest wielkością wskaźnika.

Więc w 32 bitach lub wspólny model ILP32 (integer, long, pointer) size_t wynosi 32 bity. a w 64 bitach lub w powszechnym modelu LP64 (long, pointer) size_t wynosi 64 bity (liczby całkowite to nadal 32 bity).

Są inne modele, ale są to te, których używa g++ (przynajmniej domyślnie)

 -3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-27 05:21:29