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;
?
11 answers
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_t
jest niepodpisanym typem danych zdefiniowane przez kilka standardów C / C++ , np. Norma C99 ISO / IEC 9899, to jest zdefiniowane wstddef.h
.1 może być dalej importowane przez włączeniestdlib.h
ponieważ ten plik wewnętrznie sub zawierastddef.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 zsize_t
.
Jako implikacja, size_t
jest typem gwarantowanym do przechowywania dowolnego indeksu tablicy.
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
.
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;
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
przyjmujesize_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
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
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.
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()
).
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.
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.
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
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*)
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