#c #типы_данных
Я хочу узнать что за типы такие: uint8_t, uint16_t и т. д. Слышал, что это тоже самое, что и unsigned char, unsigned short и т. д. Но в чем на самом деле разница? Созданы ли эти типы специально чтобы вне зависимости от платформы выделять для переменных определенное количество байт? Также хотелось бы узнать про size_t. Я знаю, что этот тип возвращается функцией sizeof, но в чем была необходимость его создания?
Ответы
Ответ 1
Типы int16_t, uint16_t, … — это не совсем то же самое, что и базовые целочисленные типы (англ. basic integer types) в C (char, int, short и т. д.). Основное отличие заключается в том, что для «обычных» типов стандарт определяет только одно — диапазон допустимых значений. Больше никаких требований на эти типы стандарт не налагает. Они могут быть сколь угодно широкие, их внутреннее представление может быть каким угодно, главное, чтобы сохранялась относительная ширина типов и диапазон допустимых значений. Это все, что требует стандарт. И именно эта нетребовательность стандарта позволяет быть этим типам максимально переносимыми. Другое дело — типы из . Они были введены в C99 и называются фиксированными целочисленными типами (англ. fixed integer types). На такие типы стандарт налагает гораздо больше требований. Например типы определенной ширины (англ. exact-width integer types) (int8_t, int16_t, int32_t и int64_t) должны представляться в дополнительном коде, иметь ширину в 8, 16, 32 и 64 бита соответственно и не должны содержать padding bits. Также определяются типы с шириной не меньше гарантированной; максимально широкие типы; типы, работа с которым максимально быстрая и т. д. Чувствуете эту разницу? На последние стандарт налагает гораздо больше требований, что делает их гораздо менее портабельными, но дает разработчику гораздо большую гибкость. Что, если мне нужен целочисленный тип, шириной ровно в 8 бит, или с шириной не меньше 32 бита? Стандарт предоставляет мне такую возможность на уровне языка. Возможность использования таких типов в конкретном случае зависит лишь от реализации. Вдруг, на некоторой машине в принципе не существует типов ровно в 8 бит длиной? Стандарт как бы говорит: «Нужно целочисленное число ровно в 8 бит шириной — пожалуйста, используйте int8_t, если конечно ваша реализация его поддерживает». size_t Тип size_t нужен для одного — представлять размеры объектов. Этот тип может представить максимально возможный размер любого объекта. Одно из следствий такого «свойства» — это то, что size_t — единственный тип, для которого гарантируется, что он может хранить любой возможный индекс массива (В следствии того, что массив в C — это объект). Из этого следствия вытекает частое применение этого типа как типа для различных счетчиков в цикле, которые перебирают массивы. И это единственный подходящий тип для данной задачи! Создатели языка решили определить отдельный тип для такой задачи (представление размера объектов). И вот почему. Представим, что у нас вообще нет такого типа, как size_t. И у нас стоит задача написать свой функцию strlen с использованием, например, цикла for: for (... i = 0; str[i] != '\0'; ++i) Какой тип мы будем использовать для счетчика? Может int? Но это неэффективно, так как индекс не может быть отрицательным. Тогда, пожалуй, unsigned int. Уже лучше, но что, если наша строка длиннее, чем UINT_MAX? Тогда возьмем unsigned long! Но, что если максимальная длина строки на платформе гораздо меньше ULONG_MAX и настолько большой тип будет неэффективен?.. Чтобы разработчику в такой ситуации не гадать, что да как, и был введен тип size_t. Ответ 2
Слышал, что это тоже самое что и unsigned char, unsigned short и т.д. Но в чем на самом деле разница? Это не всегда то же самое: Есть системы где например тип char беззнаковый - соотвественно uint_8 это алиас на char а не на unsigned char как можно было бы логично догадаться. Созданы ли эти типы специально чтобы вне зависимости от платформы выделять для переменных определенное количество байт? Типы uint[N]_t это беззнаковые типа гарантирующиеся быть размером в точности N бит, в то время как размеры встроенных типов unsigned char unsigned short unsigned int ... могут разнится в зависимости от реализации и платформы (а не только от платформы). Ну а вообще, надёжнее всего найти этот алиас в коде хедера и вывести его размер через стандартный sizeof оператор - так вы узнаете размер под вашу конкретную платформу и реализацию. Также хотелось бы узнать про size_t. Я знаю, что он возвращается функцией sizeof, но в чем была необходимость его создания? Цитата из вики о size_t size_t — беззнаковый целый тип, предназначенный для представления размера любого объекта в памяти (включая массивы) в конкретной реализации. Оператор sizeof возвращает значение типа size_t. Максимальный размер size_t записан в макроконстанте SIZE_MAX, определённой в (cstdint для C++). size_t должен быть, как минимум, 16 бит. К тому же POSIX включает ssize_t, который является встроенным знаковым типом, по размеру равным size_t.
Комментариев нет:
Отправить комментарий