Разница между 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.


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.


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

2

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.