Разница между size_t и unsigned int?

107

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

Мой первый вопрос: если он используется для представления только неотрицательных значений, почему бы нам не использовать unsigned intвместо size_t?

Мой второй вопрос заключается в следующем : size_tи unsigned intвзаимозаменяемы или нет? Если нет, то почему?

И может ли кто-нибудь дать мне хороший пример size_tи вкратце его работы?

Викас Верма
источник
5
typedef /*This part is implementation dependent */ size_t;
P0W 01
5
возможный дубликат беззнакового int vs. size_t

Ответы:

88

если он используется для представления неотрицательного значения, тогда почему мы не используем unsigned intвместоsize_t

Потому что unsigned intэто не только целое число без знака типа. size_tможет быть любой из unsigned char, unsigned short, unsigned int, unsigned longили unsigned long long, в зависимости от реализации.

Второй вопрос: size_tа unsigned intвзаимозаменяемы или нет, а если нет, то почему?

Они не взаимозаменяемы по причине, описанной выше ^^.

А может ли кто-нибудь дать мне хороший пример size_t и его краткую работу?

Я не совсем понимаю, что вы подразумеваете под «его кратковременной работой». Он работает как любой другой тип без знака (в частности, как тип, которому он присвоен). Рекомендуется использовать size_tпри описании размера объекта. В частности, sizeofоператор и различные стандартные библиотечные функции, такие как strlen()return size_t.

Бонус: вот хорошая статья о size_t(и тесно связанные с ptrdiff_tтипом). Это очень хорошо объясняет, почему вы должны его использовать.

Сантош Кумар
источник
1
Как именно может size_tбыть unsigned char? Это в стандарте, что это разрешено? Я имею в виду с этой идеей, как можно ожидать, что кто-то будет использовать calloc()(и семью) и strlen()т. Д.? Мне это кажется абсурдным.
Pryftan
Я думаю, что size_tв стандарте определен как «целочисленный тип без знака», но не требует, чтобы он был таким же, как любой из unsigned {char, short, int, long, long long}.
Пол Ханкин,
80

В C есть 5 стандартных целочисленных типов без знака:

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

с различными требованиями к их размерам и диапазонам (кратко, диапазон каждого типа является подмножеством диапазона следующего типа, но некоторые из них могут иметь тот же диапазон).

size_tявляется typedef(т. е. псевдонимом) для некоторого типа без знака (возможно, одного из вышеперечисленных, но возможно расширенного целочисленного типа без знака , хотя это маловероятно). Это тип, выдаваемый sizeofоператором.

В одной системе может иметь смысл использовать unsigned intдля представления размеров; с другой стороны, имеет смысл использовать unsigned longили unsigned long long. ( size_tВряд ли будет либо unsigned charили unsigned short, но это разрешено).

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

Код, который предполагает, что sizeofдает unsigned int, не будет переносимым. Код, который предполагает, что он дает a size_t, с большей вероятностью будет переносимым.

Кейт Томпсон
источник
6
Я думаю, что это должен быть принятый ответ, потому что он объясняет, почему вы должны использовать size_t
kuchi
@ keith-thompson, значит ли это, что конкретный тип (например unsigned int, unsigned longи т. д.), которому size_tсоответствует, зависит от машины, на которой выполняется код? т.е. на одной архитектуре машины он соответствует, unsigned intа на другой архитектуре будет соответствовать и unsigned longт. д.?
Ричи Томас
1
@RichieThomas: Это зависит от реализации C. Два разных компилятора с одной и той же архитектурой могут выбрать разные типы для size_t, особенно если, например, unsigned longи unsigned long longимеют одинаковый размер.
Кейт Томпсон
@RichieThomas Это тоже часть. То есть сказать , что макс long, и long longт.д. действительно зависит от системы: Если вы посмотрите на limits.hвас, по крайней мере , под юниксами видны , что максимальное значение для Интс зависит от размера слова системы.
Pryftan
1
@Pryftan Взгляните на серию Motorola 68000, а также на старую серию Intel x86 (восходящую к 8086 и 8088).
Кейт Томпсон
10

size_t имеет особое ограничение.

Цитата из http://www.cplusplus.com/reference/cstring/size_t/ :

Псевдоним одного из основных беззнаковых целочисленных типов.

Это тип, способный представлять размер любого объекта в байтах : size_t - это тип, возвращаемый оператором sizeof, и он широко используется в стандартной библиотеке для представления размеров и количества.

Он не является взаимозаменяемым, unsigned intпоскольку размер intопределяется моделью данных. Например, LLP64 использует 32-битный, intа ILP64 использует 64-битный int.

DrYap
источник
5
Откуда эта цитата? (Это не из стандарта C.)
Кейт Томпсон,
2
Вопрос помечен c . Стандарт C ++ не имеет отношения к C.
Inspectable 02
7

size_t используется для хранения размеров объектов данных и гарантированно может содержать размер любого объекта данных, который может создать конкретная реализация C. Этот тип данных может быть меньше (по количеству битов), больше или точно таким же, как unsigned int.

Томас Падрон-Маккарти
источник
4

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

Эд Хил
источник
Хорошая точка зрения. An apple- яблоко , a size_t- размер ...
dom_beau
2

Тип size_t - это базовый беззнаковый целочисленный тип языка C / C ++. Это тип результата, возвращаемого оператором sizeof. Размер типа выбирается таким образом, чтобы он мог хранить максимальный размер теоретически возможного массива любого типа. В 32-битной системе size_t займет 32 бита, в 64-битной - 64 бита. Другими словами, переменная типа size_t может безопасно хранить указатель. Исключение составляют указатели на функции класса, но это особый случай. Хотя size_t может хранить указатель, для этой цели лучше использовать другой беззнаковый целочисленный тип uintptr_t (его имя отражает его возможности). Типы size_t и uintptr_t являются синонимами. Тип size_t обычно используется для счетчиков циклов, индексации массивов и адресной арифметики. Максимально возможное значение типа size_t - константа SIZE_MAX.

user2873459
источник
1
size_tможет хранить размер любого отдельного объекта. Указатель может указывать на любой байт любого объекта. У вас может быть система, например, с 64-битным адресным пространством, которое ограничивает размер любого объекта 2 ** 32-1 байтами. Нет никакой гарантии, что size_tи uintptr_tотносятся к одному типу.
Кейт Томпсон,
2

Проще говоря, size_t зависит от платформы, а также от реализации, тогда как unsigned int зависит только от платформы.

Каушал Биллор
источник