Różnica między size_t a unsigned int?

107

Jestem taki zdezorientowany size_t. Szukałem w Internecie i wszędzie wspomniałem, że size_tjest to typ bez znaku, więc może reprezentować tylko wartości nieujemne.

Moje pierwsze pytanie brzmi: jeśli jest używany do reprezentowania tylko wartości nieujemnych, dlaczego nie użyjemy go unsigned intzamiast size_t?

Moje drugie pytanie brzmi: są size_ti unsigned intwymienne, czy nie? Jeśli nie, to dlaczego?

Czy ktoś może podać mi dobry przykład size_ti pokrótce jego działanie?

Vikas Verma
źródło
5
typedef /*This part is implementation dependent */ size_t;
P0W
5
możliwy duplikat unsigned int vs. size_t

Odpowiedzi:

87

jeśli jest używany do reprezentowania wartości nieujemnej, więc dlaczego nie używamy unsigned intzamiastsize_t

Ponieważ unsigned intnie jest to jedyny typ liczby całkowitej bez znaku. size_tmoże być dowolnego unsigned char, unsigned short, unsigned int, unsigned longlub unsigned long long, w zależności od implementacji.

Druga kwestia jest taka, że size_ti unsigned intsą wymienne, czy nie, a jeśli nie, to dlaczego?

Nie są one zamienne z powodów wyjaśnionych powyżej ^^.

Czy ktoś może mi podać dobry przykład size_t i jego krótkie działanie?

Nie do końca rozumiem, co masz na myśli, mówiąc „jego krótka praca”. Działa jak każdy inny typ bez znaku (w szczególności taki jak typ, do którego jest przypisany). Zachęcamy do używania, size_tgdy opisujesz rozmiar obiektu. W szczególności sizeofoperator i różne standardowe funkcje biblioteczne, takie jak strlen()return size_t.

Bonus: oto dobry artykuł na temat size_t(i blisko powiązany ptrdiff_ttyp). To bardzo dobrze uzasadnia, dlaczego warto go używać.

Santhosh Kumar
źródło
1
Jak dokładnie może size_tbyć unsigned char? Czy to jest w standardzie, że jest to dozwolone? Mam na myśli ten pomysł, jak można było oczekiwać, że ktokolwiek użyje calloc()(i rodziny) strlen()itp.? Wydaje mi się to absurdalne.
Pryftan
Myślę, że size_tjest zdefiniowany w standardzie jako „typ liczby całkowitej bez znaku”, ale nie wymaga, aby był taki sam jak którykolwiek z unsigned {char, short, int, long, long long}.
Paul Hankin
80

Istnieje 5 standardowych typów liczb całkowitych bez znaku w języku C:

  • unsigned char
  • unsigned short
  • unsigned int
  • unsigned long
  • unsigned long long

z różnymi wymaganiami dotyczącymi ich rozmiarów i zakresów (krótko mówiąc, zakres każdego typu jest podzbiorem zakresu następnego typu, ale niektóre z nich mogą mieć ten sam zakres).

size_tjest typedef(tj. aliasem) dla jakiegoś typu bez znaku (prawdopodobnie jeden z powyższych, ale prawdopodobnie rozszerzony typ całkowity bez znaku , chociaż jest to mało prawdopodobne). Jest to typ uzyskiwany przezsizeof operatora.

W jednym systemie sensowne może być użycie unsigned intdo reprezentowania rozmiarów; z drugiej, bardziej sensowne może być użycie unsigned longlub unsigned long long. ( size_traczej nie będzie to unsigned charalbo unsigned short, ale jest to dozwolone).

Celem programu size_tjest zwolnienie programisty z konieczności martwienia się o to, który z predefiniowanych typów jest używany do reprezentowania rozmiarów.

Kod, który zakłada, że sizeofdaje wynik i unsigned intnie byłby przenośny. Kod, który zakłada, że ​​daje wynik, size_tjest bardziej prawdopodobny do przenoszenia.

Keith Thompson
źródło
6
Myślę, że to powinna być akceptowana odpowiedź, ponieważ wyjaśnia, dlaczego powinieneś używać size_t
kuchi
@ Keith Thompson, więc to oznacza, że typ specyficzny (tj unsigned int, unsigned longitp), które size_todpowiada zależy od maszyny, na której prowadzony jest kod? tj. na jednej architekturze maszyny odpowiada, unsigned intale na innej architekturze będzie odpowiadać unsigned longitd.?
Richie Thomas
1
@RichieThomas: To zależy od implementacji C. Dwa różne kompilatory na tej samej architekturze może wybrać różne rodzaje dla size_t, szczególnie jeśli, na przykład, unsigned longi unsigned long longsą tej samej wielkości.
Keith Thompson
@RichieThomas To też część. To znaczy, że max long, long longitd. Nie zależą od systemu: Jeśli przyjrzeć się limits.hbędzie przynajmniej pod Uniksów zobaczyć, że maksymalna wartość dla wskazówki zależy od wielkości słowo systemu.
Pryftan
1
@Pryftan Spójrz na serię Motorola 68000, a także starszą serię Intel x86 (wracając do 8086 i 8088).
Keith Thompson
10

size_t ma określone ograniczenie.

Cytat z http://www.cplusplus.com/reference/cstring/size_t/ :

Alias ​​jednego z podstawowych typów liczb całkowitych bez znaku.

Jest to typ, który jest w stanie przedstawić rozmiar dowolnego obiektu w bajtach : size_t jest typem zwracanym przez operator sizeof i jest szeroko stosowany w bibliotece standardowej do reprezentowania rozmiarów i liczebności.

Nie można go stosować zamiennie z, unsigned intponieważ rozmiar intjest określony przez model danych. Na przykład LLP64 używa wersji 32-bitowej, inta ILP64 używa wersji 64-bitowej int.

DrYap
źródło
5
Skąd ten cytat? (To nie jest ze standardu C.)
Keith Thompson,
2
Pytanie jest oznaczone tagiem c . Standard C ++ nie ma związku z C.
Niespodziewane
7

size_t służy do przechowywania rozmiarów obiektów danych i gwarantuje, że będzie w stanie pomieścić rozmiar dowolnego obiektu danych, który może utworzyć dana implementacja języka C. Ten typ danych może być mniejszy (pod względem liczby bitów), większy lub dokładnie taki sam jak unsigned int.

Thomas Padron-McCarthy
źródło
4

Oprócz innych odpowiedzi dokumentuje również kod i mówi ludziom, że mówisz o rozmiarze obiektów w pamięci

Ed Heal
źródło
Słuszna uwaga. An appleto jabłko , a size_tto rozmiar ...
dom_beau
2

Typ size_t jest podstawowym typem liczby całkowitej bez znaku języka C / C ++. Jest to typ wyniku zwracanego przez operator sizeof. Rozmiar typu jest tak dobrany, aby mógł przechowywać maksymalny rozmiar teoretycznie możliwej tablicy dowolnego typu. W systemie 32-bitowym size_t zajmie 32 bity, na 64-bitowym 64 bity. Innymi słowy, zmienna typu size_t może bezpiecznie przechowywać wskaźnik. Wyjątkiem są wskaźniki do funkcji klasowych, ale jest to szczególny przypadek. Chociaż size_t może przechowywać wskaźnik, lepiej jest użyć do tego celu innego typu liczby całkowitej bez znaku uintptr_t (jego nazwa odzwierciedla jego możliwości). Typy size_t i uintptr_t są synonimami. Typ size_t jest zwykle używany do liczników pętli, indeksowania tablic i arytmetyki adresów. Maksymalna możliwa wartość typu size_t to stała SIZE_MAX.

user2873459
źródło
1
size_tmoże przechowywać rozmiar dowolnego pojedynczego obiektu. Wskaźnik może wskazywać na dowolny bajt dowolnego obiektu. Możesz mieć system z, na przykład, 64-bitową przestrzenią adresową, która ogranicza rozmiar dowolnego obiektu do 2 ** 32-1 bajtów. Nie ma gwarancji, że size_ti uintptr_tsą tego samego typu.
Keith Thompson
2

W prostych słowach size_t jest zależne od platformy i implementacji, podczas gdy unsigned int jest zależny tylko od platformy.

Kaushal Billore
źródło