Co to jest rozmiar t w C?

Mylę się z size_t w C. wiem, że jest zwracany przez operator sizeof. Ale co to dokładnie jest? Czy jest to typ danych?

Powiedzmy, że mam for pętlę:

for(i = 0; i < some_size; i++)

Czy powinienem użyć int i; Czy size_t i;?

 484
Author: Peter Mortensen, 2010-03-31

11 answers

Z Wikipedii :

Zgodnie z normą ISO C z 1999 roku (C99), size_t jest liczbą całkowitą niepodpisaną Typ co najmniej 16 bitów (patrz sekcje 7, 17 i 7, 18, 3).

size_tjest niepodpisanym typem danych zdefiniowane przez kilka standardów C / C++ , np. Norma C99 ISO / IEC 9899, to jest zdefiniowane w stddef.h.1 może być dalej importowane przez włączenie stdlib.h ponieważ ten plik wewnętrznie sub zawiera stddef.h.

Ten typ jest używany do reprezentowania na rozmiar obiektu. Funkcje biblioteki które przyjmują lub zwracają rozmiary oczekują ich być typu lub mieć typ powrotu z dnia size_t. Ponadto, najbardziej często używane Kompilatory operator sizeof powinien ocenić do stała wartość zgodna z size_t.

Jako implikacja, size_t jest typem gwarantowanym do przechowywania dowolnego indeksu tablicy.

 375
Author: sblom,
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
2016-11-22 10:30:21

size_t jest typem niepodpisanym. Nie może więc reprezentować wartości ujemnych (strlen() zwraca size_t, ponieważ długość łańcucha musi wynosić co najmniej 0.

W twoim przykładzie, jeśli indeks pętli ma być zawsze większy niż 0, może mieć sens użycie size_t lub dowolnego innego niepodpisanego typu danych.

Kiedy używasz size_t obiektu, musisz upewnić się, że w wszystkie używane konteksty, w tym arytmetyka, wymagają wartości nieujemnych. Na przykład, powiedzmy, że masz:

size_t s1 = strlen(str1);
size_t s2 = strlen(str2);

I chcesz znaleźć różnicę długości str2 i str1. Nie możesz zrobić:

int diff = s2 - s1; /* bad */

Dzieje się tak dlatego, że wartość przypisana do diff zawsze będzie liczbą dodatnią, nawet jeśli s2 < s1, ponieważ obliczenia są wykonywane z typami niepodpisanymi. W tym przypadku, w zależności od przypadku użycia, może być lepiej używać int (lub long long) dla s1 i s2.

Istnieją pewne funkcje w C/POSIX, które mogłyby / powinny używać size_t, ale nie z powodów historycznych. Na przykład drugim parametrem fgets powinno być size_t, ale int.

 184
Author: Alok Singhal,
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-06-22 08:57:04

size_t jest typem, który może pomieścić dowolny indeks tablicy.

W zależności od implementacji może to być dowolny z:

unsigned char

unsigned short

unsigned int

unsigned long

unsigned long long

Oto jak size_t jest zdefiniowane w stddef.h mojej Maszyny:

typedef unsigned long size_t;
 61
Author: Arjun Sreedharan,
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-03-04 20:48:38

Jeśli jesteś typem empirycznym

echo | gcc -E -xc -include 'stddef.h' - | grep size_t

Wyjście Dla Ubuntu 14.04 64-bit GCC 4.8:

typedef long unsigned int size_t;

Zauważ, że stddef.h jest dostarczane przez GCC, a nie glibc pod src/gcc/ginclude/stddef.h w GCC 4.2.

Ciekawe wygląd C99

  • malloc przyjmuje size_t jako argument, więc określa maksymalny rozmiar, który może zostać przydzielony.

    I ponieważ jest zwracana przez sizeof, myślę, że ogranicza maksymalny rozmiar tablicy.

    Zobacz też: The maksymalny rozmiar tablicy w C

 49
Author: Ciro Santilli 新疆改造中心 六四事件 法轮功,
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
2017-05-23 12:18:25

Strona podręcznika dla typów .h mówi:

Size_t jest typem unsigned integer

 16
Author: codaddict,
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
2010-03-31 05:56:25

Ponieważ nikt jeszcze o tym nie wspomniał, podstawowe znaczenie językowe size_t jest takie, że operator sizeof Zwraca wartość tego typu. Podobnie, podstawowym znaczeniem ptrdiff_t jest to, że odjęcie jednego wskaźnika od drugiego da wartość tego typu. Funkcje biblioteczne, które go akceptują, robią to, ponieważ pozwalają takim funkcjom pracować z obiektami, których rozmiar przekracza UINT_MAX w systemach, w których takie obiekty mogą istnieć, bez zmuszania wywołujących do marnowania kodu przekazującego wartość większą niż "unsigned int" w systemach, w których większy typ wystarczy dla wszystkich możliwych obiektów.

 11
Author: supercat,
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
2016-10-05 19:46:30

size_t i int nie są wymienne. Na przykład na 64-bitowym Linuksie size_t ma rozmiar 64-bitowy (tj. sizeof(void*)), ale int jest 32-bitowy.

Zauważ również, że {[0] } jest niepodpisana. Jeśli potrzebujesz podpisanej wersji, to na niektórych platformach istnieje ssize_t i byłoby to bardziej odpowiednie dla Twojego przykładu.

Jako ogólną zasadę proponuję używać int w większości przypadków ogólnych i używać tylko size_t/ssize_t gdy istnieje konkretna potrzeba (na przykład z mmap()).

 5
Author: dtoux,
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-04-09 06:37:33

Ogólnie rzecz biorąc, jeśli zaczynasz od 0 i idziesz w górę, Zawsze używaj typu niepodpisanego, aby uniknąć przepełnienia wprowadzającego cię w sytuację z ujemną wartością. Jest to niezwykle ważne, ponieważ jeśli granice tablic są mniejsze niż max pętli, ale pętla max jest większa niż max Twojego typu, zawiniesz się wokół wartości ujemnej i możesz doświadczyć błędu segmentacji (SIGSEGV). Tak więc, ogólnie rzecz biorąc, nigdy nie używaj int dla pętli zaczynającej się od 0 i idącej w górę. Użyj niepodpisanego.

 3
Author: Mark,
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-12-11 11:34:07

Size_t jest typem danych unsigned integer. W systemach korzystających z biblioteki GNU C będzie to unsigned int lub unsigned long int. size_t jest powszechnie używany do indeksowania tablic i zliczania pętli.

 1
Author: Prince,
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
2017-08-12 05:56:09

Size_t lub dowolny niepodpisany Typ może być postrzegany jako zmienna pętli, ponieważ zmienne pętli są zwykle większe lub równe 0.

Kiedy używamy obiektu size_t, musimy się upewnić, że we wszystkich kontekstach, w tym w arytmetyce, chcemy tylko wartości nieujemne. Na przykład, następujący program z pewnością da nieoczekiwany wynik:

// C program to demonstrate that size_t or
// any unsigned int type should be used 
// carefully when used in a loop

#include<stdio.h>
int main()
{
const size_t N = 10;
int a[N];

// This is fine
for (size_t n = 0; n < N; ++n)
a[n] = n;

// But reverse cycles are tricky for unsigned 
// types as can lead to infinite loop
for (size_t n = N-1; n >= 0; --n)
printf("%d ", a[n]);
}

Output
Infinite loop and then segmentation fault
 0
Author: bishwas pokharel,
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-05-15 18:10:30

Z mojego zrozumienia, size_t jest liczbą całkowitą unsigned, której rozmiar bitów jest wystarczająco duży, aby pomieścić wskaźnik natywnej architektury.

Więc:

sizeof(size_t) >= sizeof(void*)
 -4
Author: David Zechiel,
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-07-26 08:39:34