Есть ли в C ++ байтовый тип данных?

86

Если существует, нужно ли включить заголовочный файл?

Этот код дает ошибку компиляции:

#include <iostream>

using namespace std;

int main()
{
    byte b = 2;

    cout << b << endl;

    return 0;
}
пользователь2972135
источник
15
Это называется char.
Авидан Борисов
12
@Ben char - это обязательно один байт. Просто байт не обязательно 8 бит.
Авидан Борисов
4
@Ben: Похоже, вы не знакомы с существующими более экзотическими платформами. Байт, конечно, не определяется как 8-битный, несмотря на то, что 8-битные байты являются преобладающими. Вот почему у нас есть CHAR_BIT. Я работал над более чем одной встроенной системой, в которой байты не имеют длины 8 бит. Размер char определен как 1, так что да, char всегда является байтом.
Эд С.
11
@Ben: Стандарты C и C ++ однозначно определяют «байт» как размер a char, который составляет не менее 8 бит. Термин «байт» может быть определен по-разному в других контекстах, но при обсуждении C или C ++ лучше придерживаться определения стандарта.
Кейт Томпсон
3
ОП, я бы пересмотрел ваш принятый ответ. В самом деле. Кроме того, если char гарантированно имеет размер 1, зачем писать using byte = unsigned charи делать с ним заметки (как предлагает ответ rmp)?
einpoklum

Ответы:

35

Нет, в C ++ нет байтового типа данных. Однако вы всегда можете включить заголовок битового набора из стандартной библиотеки и создать typedef для байта:

typedef bitset<8> BYTE;

NB: Учитывая, что WinDef.h определяет BYTE для кода Windows, вы можете использовать что-то другое, кроме BYTE, если вы собираетесь настроить таргетинг на Windows.

Изменить: в ответ на предположение, что ответ неверен. Ответ не ошибочный. Возник вопрос: «Есть ли в C ++ байтовый тип данных?». Ответ был и есть: «Нет, в C ++ нет байтового типа данных», как ответил.

Что касается предложенной возможной альтернативы, для которой спросили, почему предлагаемая альтернатива лучше?

Согласно моей копии стандарта C ++, в то время:

«Объекты, объявленные как символы (char), должны быть достаточно большими, чтобы хранить любой член базового набора символов реализации»: 3.9.1.1

Я прочитал это, чтобы предположить, что если реализация компилятора требует 16 бит для хранения члена базового набора символов, то размер char будет 16 бит. То, что современные компиляторы обычно используют 8 бит для char, - это одно, но, насколько я могу судить, нет никакой гарантии, что это будет 8 бит.

С другой стороны, «битовый набор <N> шаблона класса описывает объект, который может хранить последовательность, состоящую из фиксированного числа битов, N.» : 20.5.1. Другими словами, указав 8 в качестве параметра шаблона, я получаю объект, который может хранить последовательность, состоящую из 8 бит.

Таким образом, насколько я понимаю, хотя я могу ошибаться, лучше или лучше использовать char в контексте пишущейся программы, от вашего компилятора и ваших требований в то время. Поэтому, насколько я понимаю, человек, писавший код, должен был определить, соответствует ли предложенная альтернатива его требованиям / желаниям / потребностям.

Даррен Гансберг
источник
60
Как bitset<8>лучше чем unsigned char?
Кейт Томпсон
13
Это не. используйте беззнаковый символ
ЯссерАсми
2
Ответ неверен, и все остальные неверны, кроме jwodder, который является единственно правильным ответом. byte - это биты BIT_CHAR, а не 8 бит.
Марк Галек
14
Возможно, вы захотите обновить этот ответ, так как теперь естьstd::byte
NathanOliver
1
@Persixty ой, почему я сказал BIT_CHAR. Это тайна. Тайна вселенной ..
Марк Галек
88

Нет, byteв C ++ нет типа " ". Вместо этого вы хотитеunsigned char (или, если вам нужно точно 8 бит, uint8_tиз <cstdint>, так как C ++ 11 ). Обратите внимание, что charэто не обязательно точная альтернатива, как signed charдля одних компиляторов, так и unsigned charдля других.

Jwodder
источник
8
Не совсем. char, signed charИ unsigned charтри различных типа. charимеет то же представление, что и один из двух других.
Кейт Томпсон
2
Если unsigned charбольше 8 бит, то uint8_tне будет определен.
Кейт Томпсон
1
если вы используете objective-c, вам может потребоваться включить <stdint.h>вместо <cstdint>.
orion elenzil 07
2
@orionelenzil Вопрос касался C ++, а не объективного C.
Pharap 02
2
@pharap - мой комментарий может оказаться полезным для тех, кто пишет C или C ++ в контексте Objective-C.
Орион Элензил 02
42

Да, есть std::byte(определено в<cstddef> ).

C ++ 17 представил это.

maxschlepzig
источник
2
std::byteне может выполнять арифметические операции, что может нарушить условия сделки.
Pharap 02
3
@Pharap, это зависит от обстоятельств - невозможность случайно выполнить арифметику может рассматриваться как преимущество в некоторых случаях использования. Так как std::byteэто всего лишь дополнение можно выбрать правильный инструмент для работы (т.е. либо std::byte, char, unsigned charили uint_8).
maxschlepzig 02
27

если вы используете окна, в WinDef.h у вас есть:

typedef unsigned char BYTE;
rmp
источник
22

Использование C++11есть версия хорошо для вручную определенного типа байт:

enum class byte : std::uint8_t {};

По крайней мере, это то, что делает GSL .

Начиная с C++17(почти), эта версия определяется в стандарте как std::byte(спасибо Нилу Макинтошу за оба).

m8mble
источник
4
Почему, на ваш взгляд, это перечисление лучше, чем typedef unsigned char byte;или typedef std::uint8_t byte;?
einpoklum
2
@einpoklum, это увеличивает безопасность типов. Например, вы получите ошибку компиляции, если случайно умножите такое байтовое значение. Хотя с алиасингом это не помогает . Если вы хотите правильно указать какие-то байты, которые вам нужны char*, unsigned char*или std::byte*.
maxschlepzig
1
За исключением std::byteтого, что над ним нельзя выполнять арифметические операции, что может помешать сделке.
Pharap 02
1
namespace std
{
  // define std::byte
  enum class byte : unsigned char {};

};

Это, если ваша версия C ++ не имеет std :: byte, будет определять тип байта в пространстве имен std. Обычно вы не хотите добавлять что-либо в std, но в данном случае это стандартная вещь, которой не хватает.

std :: byte из STL выполняет гораздо больше операций.

Крис Рид
источник