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


86

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

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

#include <iostream>

using namespace std;

int main()
{
    byte b = 2;

    cout << b << endl;

    return 0;
}

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для других.


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 представил это.


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;

22

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

enum class byte : std::uint8_t {};

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

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


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 выполняет гораздо больше операций.

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