Что такое размер t в C?



я путаюсь с size_t в C. Я знаю, что он возвращается sizeof оператора. Но что именно это? Это тип данных?



Допустим у меня есть for петли:



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


Я должен использовать int i; или size_t i;?

8822   11  

11 ответов:

Из Википедии:

согласно стандарту 1999 ИСО к (C99),size_t - Это целое число без знака тип не менее 16 бит (см. разделы 7.17 и 7.18.3).

size_t - Это тип данных без знака определяется несколькими стандартами C / C++ , например, стандарт C99 ISO / IEC 9899, это определяется в stddef.h.1 он может быть дополнительно импортированы путем включения stdlib.h как этот файл внутри суб включает stddef.h.

этот тип используется для представления размер объекта. Библиотечная функция которые принимают или возвращают размеры ожидают их типа или типа возврата из size_t. Кроме того, большинство часто используемый компилятор на основе оператор sizeof должен оценить до a постоянное значение, совместимое с size_t.

как следствие,size_t - Это тип, который гарантированно содержит любой индекс массива.

size_t - Это тип без знака. Таким образом, он не может представлять никаких отрицательных значений(strlen() возвращает a size_t потому что длина строки должна быть не менее 0.

в вашем примере, если ваш индекс цикла будет всегда больше 0, может иметь смысл использовать size_t, или любой другой тип данных без знака.

при использовании size_t объект, вы должны убедиться, что во всех контекстах он используется, включая арифметику, вы хотите неотрицательные значения. Например, допустим, у вас есть:

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

и вы хотите найти разницу длин str2 и str1. Вы не можете сделать:

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

это потому, что значение, присвоенное diff всегда будет положительным числом, даже когда s2 < s1, потому что расчет выполняется с беззнаковыми типами. В этом случае, в зависимости от каков ваш вариант использования, вам может быть лучше использовать int (или long long) для s1 и s2.

в C/POSIX есть некоторые функции, которые могут / должны использовать size_t, но не из-за исторических причин. Например, второй параметр fgets в идеале должно быть size_t, но это int.

size_t - Это тип, который может содержать любой индекс массива.

в зависимости от реализации, это может быть любой из:

unsigned char

unsigned short

unsigned int

unsigned long

unsigned long long

вот как size_t определена в stddef.h моя машина:

typedef unsigned long size_t;

если вы эмпирический тип

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

выход для Ubuntu 14.04 64-разрядный GCC 4.8:

typedef long unsigned int size_t;

отметим, что stddef.h предоставляется GCC, а не glibc под src/gcc/ginclude/stddef.h в GCC 4.2.

интересные выступления C99

  • malloc принимает size_t как аргумент, он определяет максимальный размер, который может быть выделен.

    и так как он также возвращается sizeof, Я думаю, что это ограничивает максимальный размер любого массива.

    Читайте также: максимальный размер массива в C

на странице справочника типы.h говорит:

size_t должен быть целочисленным типом без знака

поскольку никто еще не упомянул об этом, первичное лингвистическое значение size_t Это sizeof оператор возвращает значение этого типа. Аналогично, первичное значение ptrdiff_t это вычитание одного указателя из другого даст значение этого типа. Библиотечные функции, которые принимают его, делают это, потому что это позволит таким функциям работать с объектами, размер которых превышает UINT_MAX в системах, где такие объекты могут существовать, не заставляя вызывающих абонентов тратить код, передавая значение больше, чем" unsigned int " в системах, где более крупный тип будет достаточным для всех возможных объектов.

size_t и int не заменимы. Например, на 64-битном Linux size_t имеет 64-битный размер (т. е. sizeof(void*)), но int 32-битные.

также обратите внимание, что size_t не подписан. Если вам нужна подписанная версия, то есть ssize_t на некоторых платформах и это было бы более уместно для вашего примера.

как правило, я бы предложил использовать int для большинства общих случаев и использовать только size_t/ssize_t когда есть конкретная потребность в ней (с mmap() например).

В общем случае, если вы начинаете с 0 и идете вверх, всегда используйте тип без знака, чтобы избежать переполнения, приводящего вас в ситуацию отрицательного значения. Это критически важно, потому что если ваши границы массива оказываются меньше, чем max вашего цикла, но ваш цикл max оказывается больше, чем max вашего типа, вы обернете вокруг отрицательного, и вы можете испытать ошибка сегментирования (SIGSEGV). Поэтому, в общем случае, никогда не используйте int для цикла, начинающегося с 0 и идущего снизу вверх. Используйте без знака.

size_t-это беззнаковый целочисленный тип данных. В системах, использующих библиотеку GNU C, это будет unsigned int или unsigned long int. size_t обычно используется для индексации массива и подсчета циклов.

реализация или любой беззнаковый тип может рассматриваться как переменная цикла, поскольку переменные цикла обычно больше или равны 0.

при использовании реализация объект, мы должны убедиться, что во всех контекстах он используется, включая арифметику, мы хотим только неотрицательные значения. Например, следующая программа определенно даст неожиданный результат:

// 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

в моем понимании, size_t это unsigned целое число, размер бита которого достаточно велик, чтобы содержать указатель собственной архитектуры.

Так:

sizeof(size_t) >= sizeof(void*)

Comments

    Ничего не найдено.