Тип для представления байта в ANSI (C89 / 90) C?

Существует ли метод подачи жалоб на стандарты для представления байта в ANSI (C89 / 90) C? Я знаю, что чаще всего char бывает байтом, но я понимаю, что это не гарантируется. Кроме того, в стандарте C99 есть stdint.h, но что использовалось до C99?

Меня интересуют как 8 бит, так и «байт» (sizeof (x) == 1).

Убедитесь, что вы отличаете байт от октета. sizeof (char) = 1 always, что означает, что char всегда является байтом. Однако байт не всегда является октетом (байты DEC Alpha были 10 битами, IIRC ... октеты определены как 8 бит).

Tom 13.01.2009 07:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
35
1
23 066
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

До C99? Платформо-зависимый код.

Но почему тебя это волнует? Просто используйте stdint.h.

В каждой реализации C, которую я использовал (от старого UNIX до встроенных компиляторов, написанных инженерами по оборудованию, и до компиляторов крупных производителей) char всегда был 8-битным.

Итак, ваш совет: использовать uint8_t или использовать unsigned char?

Chris Conway 13.01.2009 03:42

Забавно, когда я ходил в школу, персонаж был 6-битным. Строчная стоимость 12 бит! Я так понимаю, вы не пропустите 36-битные, 60-битные и другие забавные машины, с которыми мы привыкли работать.

Will Hartung 13.01.2009 04:43

Вы можете найти довольно надежные макросы и определения типов в boost.

Ну, вы можете просто скопировать / вставить оттуда то, что вам нужно. Нет ничего особенного, если вам нужен только надежный тип целых чисел определенной длины.

PolyThinker 13.01.2009 04:04

Вы всегда можете представить байт (если вы имеете в виду 8 бит) в беззнаковом символе. Он всегда имеет размер не менее 8 бит, все биты составляют значение, поэтому в него всегда будет помещаться 8-битное значение.

Если вам нужно ровно 8 бит, я также думаю, что вам придется использовать способы, зависящие от платформы. Системы POSIX кажутся обязательный для поддержки int8_t. Это означает, что в системах POSIX char (и, следовательно, байт) всегда 8 бит.

Поддержка POSIX для stdint.h после даты C99.

Chris Conway 13.01.2009 03:47

о да. похоже, из 2001 года. но я думаю, что даже если у него нет компилятора c99, поставляющего его - если он на машине posix, он может воспользоваться его требованиями из stdint.h. если он в окнах ms, все мои ставки отключены :) может быть, он сможет взять что-то из cstdint.hpp boost и c'ify?

Johannes Schaub - litb 13.01.2009 03:55

Я имею в виду байт, не обязательно 8 бит, но спасибо. Кстати, в спецификации сказано, что он должен быть не менее 8 бит, или это просто так?

Sydius 13.01.2009 05:30

да, стандартное документирование limits.h требует, чтобы UCHAR_MAX был не менее 255, не имел битов заполнения и использовал чистую двоичную систему. char должен иметь тот же диапазон и представление, что и unsigned char или signed char, но все же должен быть отдельным типом.

Johannes Schaub - litb 13.01.2009 15:15
Ответ принят как подходящий

char всегда является байт, но не всегда октет. Байт - это наименьшая адресуемая единица памяти (в большинстве определений), октет - это 8-битная единица памяти.

То есть sizeof(char) всегда 1 для всех реализаций, но макрос CHAR_BIT в limits.h определяет размер байта для платформы, и это не всегда 8 бит. Существуют платформы с 16-битными и 32-битными байтами, поэтому char будет занимать больше бит, но это по-прежнему байт. Поскольку требуемый диапазон для char составляет от -127 до 127 (или от 0 до 255), на всех платформах он будет равен 8 битам по меньшей мере.

ISO/IEC 9899:TC3

6.5.3.4 The sizeof operator

  1. ...
  2. The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. [...]
  3. When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1. [...]

Акцент мой.

Просто для пояснений, всегда ли sizeof (char) 1 в спецификации или просто присутствует во всех реализациях?

Sydius 13.01.2009 05:28

Предполагая, что вы используете нечетную архитектуру с <8-битным байтом, не может ли char не быть байтом (поскольку CHAR_BITS> = 8)? Если нет, не могли бы вы точно определить, что вы подразумеваете под словом «байт» выше?

Chris Conway 13.01.2009 19:34

Требуемый диапазон для char на самом деле составляет от -127 до 127 (не забывайте, что в некоторых архитектурах используется знаковая величина или представление целого числа с дополнением) или от 0 до 255, в зависимости от того, является ли char знаковым или беззнаковым. 8-битное дополнение до двух поддерживает от -128 до 127, а не от -127 до 128.

bk1e 14.01.2009 10:48

@Chris: byte = наименьшая адресуемая единица памяти. Я не совсем понимаю, что вы имеете в виду под своим вопросом. байт меньше 8 бит означает, что платформа не может быть совместима с C.

Alex B 14.01.2009 11:37

Не понимал, что C требует> = 8-битных байтов (действительно, стандарт говорит, что байт должен содержать char, а char должен быть 8 бит). Мы достигли предела портативности C ...

Chris Conway 14.01.2009 19:36

Какие платформы имеют байты больше 8 бит?

theduke 02.10.2011 04:22

@theduke, в основном DSP, например: leo.sprossenwanne.at/dsp/Entwicklungsprogramme/Entpack/CC56/‌ DSP /…

Alex B 02.10.2011 07:10

Байт физического оборудования меньше 8 бит не является проблемой с точки зрения соответствия C, пока логический байт, представленный реализацией C, составляет не менее 8 бит. Это означает, что машина с 7-битными аппаратными байтами может предоставить 14-битный логический байт для char и быть совместимой, но тогда все более крупные типы должны будут занимать целое (и выровненное) количество таких логических байтов (т. Е. У вас не может быть 21-битное целое число, состоящее из 3 аппаратных байтов, если вы не включили вместе с ним дополнительные 7 битов заполнения (остальная часть второго char).

R.. GitHub STOP HELPING ICE 21.10.2011 08:54

В ANSI C89 / ISO C90 sizeof (char) == 1. Однако не всегда 1 байт равен 8 битам. Если вы хотите подсчитать количество бит в 1 байте (и у вас нет доступа к limits.h), я предлагаю следующее:

unsigned int bitnum(void) {
    unsigned char c = ~0u; /* Thank you Jonathan. */
    unsigned int v;

    for(v = 0u; c; ++v)
        c &= c - 1u;
    return(v);
}

Здесь мы используем метод Кернигана для подсчета количества битов, установленных в c. Чтобы лучше понять приведенный выше код (или увидеть другие похожие), я отсылаю вас к «Bit Twiddling Хаки».

Лучше использовать ~ 0, чем -1; на машине с дополнением до единицы или знаковой величиной -1 может не быть полностью битовым. ~ 0 гарантированно будет установлен всеми битами.

Jonathan Leffler 13.01.2009 07:31

@ Джонатан: В этом есть смысл. Спасибо за предложение. Я сейчас редактирую пост. (Мне очень жаль, что я так много раз редактировал этот комментарий!)

anon 13.01.2009 07:52

-1 всегда все биты единица. преобразование -1 в беззнаковый char не обязательно сохраняет бит (усечение)

Johannes Schaub - litb 13.01.2009 15:17

он определен математически: -N is (2 ^ CHAR_BIT - (N mod (2 ^ CHAR_BIT))), что означает, что -1 всегда является самым высоким беззнаковым символом, имеющим все биты 1. Разница в представлении знака заключается в том, что если вы имеют дополнение до двух, преобразование здесь концептуальное: битовая комбинация не изменится:

Johannes Schaub - litb 13.01.2009 15:21

в то время как -1 - это все биты 1 до этого, то же самое и после преобразования в беззнаковый char. придирки (мне это действительно не нравится, но, чтобы быть правильным :)), ~ 0u может (после преобразования) вместо этого привести к другому значению, чем all-bits-1: преобразование значения в unsigned char будет обернуто вокруг N = > N по модулю 2 ^ CHAR_BIT

Johannes Schaub - litb 13.01.2009 15:36

... означает, что если N не кратно UCHAR_MAX (что может произойти, потому что беззнаковое int не должно использовать все свои биты для хранения своего значения), вы можете остаться со значением, не обязательным для всех битов 1. поэтому Я думаю, что ваша первая версия, преобразовывающая -1 в беззнаковый символ, была в порядке. пожалуйста, скажите мне, если я ошибаюсь

Johannes Schaub - litb 13.01.2009 15:36

чтобы процитировать его напрямую: «В противном случае, если новый тип беззнаковый, значение преобразуется путем многократного добавления или вычитания на единицу большего, чем максимальное значение, которое может быть представлено в новом типе, пока значение не окажется в диапазоне нового типа. "

Johannes Schaub - litb 13.01.2009 15:41

(говоря «-1 - это всегда все биты один», я имею в виду, что -1 преобразовано в беззнаковый символ, как в вашем ответе. -1 сам по себе, конечно, только все биты один для двух дополнений). для дополнения до двух преобразование не меняет биты. комментарии слишком короткие, чтобы говорить правду :)

Johannes Schaub - litb 13.01.2009 20:39

Я почти уверен, что (unsigned char) -1 не установит все биты на машине, которая использует либо дополнение до единиц, либо знаковое представление чисел со знаком.

anon 14.01.2009 01:10

@anon: Вы можете быть уверены, но вы тоже ошибаетесь. (unsigned_type)-1 - это биты "все единицы" всегда в типе назначения.

R.. GitHub STOP HELPING ICE 21.10.2011 08:56

@R: Как такое может быть? Дополнение до единицы означает, что для 16-битных целых чисел -1 равно% 11111111-11111110, потому что для получения отрицательного числа биты просто переворачиваются (глянь сюда). Только для двух дополнений -1 будет% 11111111-11111111, то есть 0x7FFFF + 1 (когда многие процессоры любезно устанавливают флаг переполнения).

Andreas Spindler 24.10.2012 01:23

@AndreasSpindler: см. Комментарий JohannesSchaub-litb: преобразование из подписанного в беззнаковый - это не просто переинтерпретация битового шаблона, концептуально вы добавляете Uxxx_MAX, пока не попадете в диапазон.

ninjalj 23.02.2015 21:47

Я заметил, что некоторые ответившие изменили определение слова «байт» на что-то иное, чем 8 бит. Байт равен 8 битам, однако в некоторых реализациях c char составляет 16 бит (2 байта) или 8 бит (1 байт). Люди, которые называют байт «наименьшей адресуемой единицей памяти» или подобным мусором, потеряли понимание значения байта (8 бит). Причина того, что некоторые реализации C имеют 16-битные символы (2 байта), а некоторые - 8-битные символы (1 байт), и не существует стандартного типа, называемого «байтом», - это лень.

Итак, мы должны использовать int_8

языковой стандарт определил это значение слова «байт» как наименьшую адресуемую единицу. Это не обязательно должно быть 8 бит. В некоторых системах он может быть больше. Маловероятно, что в этих системах даже будет int_8 (или int8_t).

Bo Persson 12.06.2011 21:55

Не просто маловероятно. int8_t требуется, если он существует, не иметь битов заполнения (и представления дополнения до двух), поэтому единственный способ его существования - это если char имеет ровно 8 бит.

R.. GitHub STOP HELPING ICE 21.10.2011 08:58

Байт традиционно нет означал 8 бит. Например: основная причина, по которой FTP использует отдельные соединения для управления и передачи данных, заключается в том, чтобы иметь возможность выбрать соответствующий размер байта для соединения для передачи данных, например, для 36-битных компьютеров. Обратите внимание, что в RFC используется термин октет (и избегайте использования неоднозначного термина «байт») для обозначения 8-битного блока данных.

ninjalj 23.02.2015 22:10

Другие вопросы по теме