Как символ может быть представлен битовым шаблоном, содержащим три восьмеричных цифры?

Из главы 2 (подраздел 2.3 под названием «Константы») книги K&R по языку программирования C:

Определенные символы могут быть представлены в символьных и строковых константах с помощью управляющих последовательностей, таких как \n (новая строка); эти последовательности выглядят как два символа, но представляют только один. Кроме того, битовая комбинация произвольного размера в байтах может быть указана с помощью

′\ooo′

где ooo — от одной до трех восьмеричных цифр (0...7) или

′\xhh′

где hh — одна или несколько шестнадцатеричных цифр (0...9, a...f, A...F). Так что мы могли бы написать

#define VTAB ′\013′    /* ASCII vertical tab */
#define BELL ′\007′    /* ASCII bell character */

or, in hexadecimal,
#define VTAB ′\xb′     /* ASCII vertical tab */
#define BELL ′\x7′     /* ASCII bell character */

Меня смущают следующие формулировки (выделено мной): где ooo — от одной до трех восьмеричных цифр (0...7). Если есть три восьмеричных цифры, требуемое количество битов будет 9 (3 для каждой цифры), что превышает длину байта, необходимую для символов. Наверняка я что-то здесь упускаю. Что мне не хватает?


person Geek    schedule 09.08.2013    source источник
comment
which exceeds the byte length required for characters. неправильно. Машины могут иметь 9-битные символы. Или 7 бит. (или даже 16 бит) '\377' - это только константы, служащие инициализаторами. Компилятор всегда может пожаловаться, если значения не помещаются в машинный символ.   -  person wildplasser    schedule 09.08.2013


Ответы (3)


\ooo (3 восьмеричных цифры) действительно позволяет указывать 9-битные значения от 0 до 111111111 (двоичные) или 511. Если это разрешено, это зависит от размера char.

Назначения, подобные приведенным ниже, генерируют предупреждение во многих средах, поскольку в этих средах char имеет 8 бит. Обычно наивысшая допустимая восьмеричная последовательность — \377. Но char не обязательно должно быть 8 бит. ОП «9... превышает длину байтов, необходимую для символов» неверен.

char *s = "\777";  //warning "Octal sequence out of range"
char c  = '\777';  //warning
int i   = '\777';  //warning

Константа из трех восьмеричных цифр '\141' аналогична 'a' в типичной среде, где используется ASCII. Но в альтернативном наборе символов 'a' может быть другим. Таким образом, если кто-то хочет назначить переносимый битовый шаблон 01100001, можно использовать '\141' вместо 'a'. То же самое можно было бы сделать, назначив '\x61'. В некоторых случаях может быть предпочтительнее восьмеричный шаблон.

C11 6.4.4.4.9 Если префикс не используется, «значение восьмеричной или шестнадцатеричной управляющей последовательности должно находиться в диапазоне представляемых значений для соответствующего типа: unsigned char»

person chux - Reinstate Monica    schedule 09.08.2013
comment
Почему int i = '\777'; должно выдавать предупреждение? - person Geek; 10.08.2013
comment
@Geek '\777', вероятно, выдает предупреждение самому себе. Он пытается представить char, но выходит за пределы диапазона 8-битного char. Тот факт, что int может содержать 9+ бит, не является источником предупреждения. хотя можно сделать int i = 0777 (нет '). - person chux - Reinstate Monica; 10.08.2013

Насколько я помню, диапазон кодовых номеров символов в K&R не определен. В первые дни это обычно был диапазон ASCII 0...127. В настоящее время это часто 8-битный диапазон, 0...255, но он может быть и шире. В любом случае ограничения, определенные реализацией для типа данных char, также подразумевают ограничения для escape-нотаций.

Например, если диапазон составляет 0...127, то \177 является самым большим допустимым восьмеричным переходом.

person Jukka K. Korpela    schedule 09.08.2013
comment
Для справки: в настоящее время C11 5.2.4.2.1 количество битов для наименьшего объекта, который не является битовым полем (байт) ›= 8. (CHAR_BIT). - person chux - Reinstate Monica; 10.08.2013

Первая восьмеричная цифра может быть только 3 (два бита), а не 7 (три бита), если мы говорим о восьмибитных байтах. Если мы говорим об ASCII (7-битные значения), первая цифра может быть только нулем или единицей.

Если K&R говорит иначе, их описание либо неполное, либо неверное.

person Robert Harvey    schedule 09.08.2013
comment
Почему так? Можете ли вы уточнить? - person Geek; 09.08.2013
comment
Вы уже указали причину: байт может содержать только восемь бит. На самом деле, поскольку мы говорим об ASCII, первая цифра может быть только нулем или единицей, поскольку ASCII определяется 7 битами, а не 8. - person Robert Harvey; 09.08.2013
comment
Я не думаю, что ASCII упоминается ни в K&R, ни в более поздних стандартах C. Набор символов требуется только для размещения букв, цифр и NUL, IIRC. Были предприняты большие меры предосторожности, чтобы поддержать EBDIC et.al. - person wildplasser; 09.08.2013
comment
@wildplasser: Достаточно справедливо, но ограничения остаются в силе. - person Robert Harvey; 09.08.2013