Подтвердить что ты не робот

Почему size_t, когда int будет достаточным для размера массива?

Стандарт C гарантирует, что int может хранить все возможные размеры массива. По крайней мере, это то, что я понимаю из чтения §6.5.2.1, подраздел 1 (Ограничения подписи):

Одно из выражений должно иметь тип '' указатель на тип объекта, другое выражение должно имеют целочисленный тип, а результат имеет тип type.

Поскольку мы будем использовать int как индексы массива, почему мы должны использовать size_t для определения размера массива?

Почему strlen() возвращает size_t, когда int будет достаточно?

4b9b3361

Ответ 1

Термин "целочисленный тип" не означает int - например, char, а short - целые типы.

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

Более конкретно, size_t vs. int, одним из примеров может быть платформа, где int может быть 16-разрядным типом, а size_t может быть 32-разрядным (или более обычным 32-разрядным int против 64-разрядной разницы size_t на сегодняшних 64-разрядных платформах).

Ответ 2

целочисленный тип не обязательно является "int". "long long" также является целым типом, как и "size_t".

Массивы могут быть больше 2 ГБ. Это свойство весьма удобно для тех, кто пишет голодные программы для хранения данных, например СУБД с большими пулами буферов, серверы приложений с большими кэшами памяти и т.д. Массивы размером более 2 ГБ /4 ГБ - это всего лишь 64-разрядные вычисления:)

size_t для strlen(), по крайней мере, звучит совместимо с тем, как C-стандартный обрабатывает массивы, имеет ли он практический смысл или нет, или кто-то видел большие строки, это другой вопрос.

Ответ 3

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

Во-вторых, язык C на самом деле не имеет "подписки на массивы". Подписка на массивы реализована с помощью арифметики указателя. И интегральный операнд в арифметике указателя имеет тип ptrdiff_t. Не size_t, а не int, но ptrdiff_t. Это подписанный тип, BTW, что означает, что значение может быть отрицательным.

В-третьих, целью size_t является сохранение размера любого объекта в программе (т.е. сохранение результата sizeof). Он не предназначен для использования в качестве индекса массива. Это просто работает как индекс массива, поскольку гарантируется, что он всегда достаточно велик, чтобы индексировать любой массив. Однако с абстрактной точки зрения "массив" представляет собой определенный тип "контейнера", и есть другие типы контейнеров (списки на основе, древовидные и т.д.). В общем случае size_t недостаточно для хранения размера любого контейнера, что в общем случае делает его сомнительным выбором для индексации массива. (strlen, с другой стороны, это функция, которая работает с массивами специально, что делает там size_t.)

Ответ 4

Когда был написан стандарт C, для машин было типично 16-битный тип "int", и он не мог обрабатывать ни один объект размером больше 65535 байтов, но тем не менее он способен обрабатывать объекты размером более 32767 байт. Так как арифметика на unsigned int будет достаточно большой, чтобы обрабатывать наибольшие размер таких объектов, но арифметика на подписанном int не была бы определена, size_t быть неподписанным, чтобы разместить такие объекты без необходимости использовать "длинные", вычисления.

На машинах, где максимально допустимый размер объекта находится между INT_MAX и UINT_MAX, разница между указателями на начало и конец таких объект может быть слишком большим, чтобы соответствовать "int". Хотя Стандарт не налагает любые требования к тому, как реализация должна справиться с этим, общий подход состоит в том, чтобы определить поведение целочисленного и указательного обертывания таким образом, что если S и E являются указателями на начало и конец char [49152], тогда даже если E-S превысит INT_MAX, он даст значение, которое при добавлении к S будет выход E.

В настоящее время редко существует реальное преимущество в том, что size_t является unsigned type (поскольку код, который требует объектов размером более 2 ГБ, часто необходимо использовать 64-битные указатели по другим причинам), и это вызывает много видов сравнения с размерами объектов, которые ведут себя контр-интуитивно, но факт, что выражения sizeof дают неподписанный тип достаточно хорошо что он вряд ли когда-либо изменится.

Ответ 5

size_t - это typedef целого числа без знака (например, int или long).

В некоторых 64-битных платформах int может быть 32 бит, а size_t может быть 64 бит.

Используется как более стандартный способ для размера.