В чем преимущество использования uint8_t
над unsigned char
C?
Я знаю, что почти в каждой системе uint8_t
есть просто typedef unsigned char
, так зачем его использовать?
Он документирует ваше намерение - вы будете хранить маленькие цифры, а не персонажа.
Также это выглядит лучше, если вы используете другие определения типа, такие как uint16_t
или int32_t
.
unsigned char
илиsigned char
документирование намерений тоже, так как неукрашенныеchar
это то, что показывает, что вы работаете с символами.unsigned
былunsigned int
по определению?char
кажется, подразумевает символ, тогда как в контексте строки UTF8, это может быть только один байт многобайтового символа. Использование uint8_t может прояснить, что не следует ожидать символа в каждой позиции - другими словами, что каждый элемент строки / массива является произвольным целым числом, о котором не следует делать никаких семантических предположений. Конечно, все программисты на Си знают это, но это может подтолкнуть новичков к постановке правильных вопросов.Просто чтобы быть педантичным, некоторые системы могут не иметь 8-битного типа. Согласно Википедии :
Так
uint8_t
что не гарантируется существование, хотя это будет для всех платформ, где 8 бит = 1 байт. Некоторые встроенные платформы могут отличаться, но это происходит очень редко. Некоторые системы могут определятьchar
типы как 16-битные, и в этом случае, вероятно, не будет 8-битного типа.Помимо этой (незначительной) проблемы, ответ @Mark Ransom является лучшим, на мой взгляд. Используйте тот, который наиболее четко показывает, для чего вы используете данные.
Кроме того, я предполагаю, что вы имели в виду
uint8_t
(стандартный typedef от C99, представленный вstdint.h
заголовке), а неuint_8
(не является частью какого-либо стандарта).источник
uint8_t
(или typedef его к этому). Это связано с тем, что 8-битный тип имел бы неиспользуемые биты в представлении хранилища, чегоuint8_t
не должно быть.typedef unsigned integer type uint8_t; // optional
Так что, по сути, стандартная соответствующая библиотека C ++ вообще не нужна для определения uint8_t (см. Комментарий // необязательно )Весь смысл в том, чтобы написать независимый от реализации код.
unsigned char
не гарантируется быть 8-битным типом.uint8_t
есть (если есть).источник
sizeof(unsigned char)
вернется1
за 1 байт. но если системные char и int имеют одинаковый размер, например, 16-битный, тоsizeof(int)
также вернется1
Как вы сказали, « почти каждая система».
char
Вероятно, это один из менее вероятных изменений, но как только вы начнете использоватьuint16_t
и друзей,uint8_t
лучше использовать смеси, и даже можете стать частью стандарта кодирования.источник
По моему опыту, есть два места, где мы хотим использовать uint8_t для обозначения 8 бит (и uint16_t и т. Д.) И где мы можем иметь поля размером менее 8 бит. В обоих случаях пространство имеет значение, и нам часто приходится смотреть на необработанный дамп данных при отладке и иметь возможность быстро определить, что он представляет.
Первый касается радиочастотных протоколов, особенно в узкополосных системах. В этой среде нам может понадобиться собрать как можно больше информации в одно сообщение. Второй - во флэш-памяти, где у нас может быть очень ограниченное пространство (например, во встроенных системах). В обоих случаях мы можем использовать упакованную структуру данных, в которой компилятор позаботится о упаковке и распаковке для нас:
Какой метод вы используете, зависит от вашего компилятора. Вам также может потребоваться поддержка нескольких разных компиляторов с одинаковыми заголовочными файлами. Это происходит во встроенных системах, где устройства и серверы могут быть совершенно разными - например, у вас может быть устройство ARM, которое взаимодействует с сервером Linux x86.
Есть несколько предостережений с использованием упакованных структур. Самое важное, что вы должны избегать разыменования адреса члена. В системах с выровненными по многобайтовым словам словами это может привести к смещенному исключению - и coredump.
Некоторые люди также будут беспокоиться о производительности и утверждают, что использование этих упакованных структур замедлит работу вашей системы. Это правда, что за кулисами компилятор добавляет код для доступа к невыровненным элементам данных. Это можно увидеть, посмотрев код сборки в вашей IDE.
Но поскольку упакованные структуры наиболее полезны для связи и хранения данных, данные могут быть извлечены в неупакованное представление при работе с ним в памяти. Обычно нам вообще не нужно работать со всем пакетом данных в памяти.
Вот некоторые соответствующие обсуждения:
пакет pragma (1) и __attribute__ ((выровненный (1))) работает
Небезопасен ли пакет gcc для __attribute __ ((упакованный)) / #pragma?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
источник
Там мало С точки зрения переносимости, он
char
не может быть меньше 8 бит, и ничто не может быть меньшеchar
, поэтому, если данная реализация C имеет 8-разрядный целочисленный тип без знака, это произойдетchar
. Альтернативно, у этого может не быть вообще ни одного, в котором пункте любыеtypedef
уловки являются спорными.Это может быть использовано для лучшего документирования вашего кода в том смысле, что вам очевидно, что вам нужны 8-битные байты и больше ничего. Но на практике это разумное ожидание практически где-то уже (есть платформы DSP, на которых это не так, но шансы на то, что ваш код работает там, невелики, и вы могли бы также с ошибкой использовать статическое утверждение вверху вашей программы на такая платформа).
источник
unsigned char
чтобы можно было хранить значения в диапазоне от 0 до 255. Если вы можете сделать это в 4 битах, моя шляпа для вас.uint8_t
к реализации. Интересно, компиляторы для DSP с 16-битными символами обычно реализуютuint8_t
или нет?#include <stdint.h>
и использоватьuint8_t
. Если у платформы есть это, это даст это Вам. Если у платформы его нет, ваша программа не будет компилироваться, и причина будет ясна и понятна.Это действительно важно, например, когда вы пишете сетевой анализатор. заголовки пакетов определяются спецификацией протокола, а не тем, как работает компилятор C конкретной платформы.
источник
Почти на каждой системе я встречал uint8_t == unsigned char, но это не гарантируется стандартом C. Если вы пытаетесь написать переносимый код, и важно, какой именно размер памяти, используйте uint8_t. В противном случае используйте неподписанный символ.
источник
uint8_t
всегда соответствует диапазону, размеруunsigned char
и отступу (нет), когдаunsigned char
8-битный. Когдаunsigned char
не 8-битный,uint8_t
не существует.unsigned char
это 8-бит, будетuint8_t
гарантированно будетtypedef
их , а неtypedef
из расширенного целого числа без знака типа ?unsigned char/signed char/char
и самый маленький тип - не менее 8 бит.unsigned char
не имеет отступов. Для того,uint8_t
чтобы быть, это должно быть 8 битов, без заполнения, существуют из-за реализации целочисленного типа, обеспеченного: соответствие минимальным требованиямunsigned char
. Что касается "... гарантированно будет typedef ...", то это хороший вопрос для публикации.