Цель использования восьмеричного для ASCII

Зачем программисту C использовать escape-последовательности (oct/hex) для значений ASCII, а не десятичные?

Дополнение: связано ли это с производительностью или переносимостью?

Пример:

char c = '\075';

person frogleaf    schedule 08.01.2015    source источник
comment
8 не является допустимой восьмеричной цифрой, не так ли?   -  person M Oehm    schedule 08.01.2015
comment
нет, совсем нет   -  person frogleaf    schedule 08.01.2015
comment
Когда код читался как '\085', это была многосимвольная символьная константа с нулем, за которым следовали цифры 8 и 5, что приводило к всевозможным странностям. Многосимвольные символьные константы имеют интерпретацию, определяемую реализацией, и присвоение одной простой char (вместо, возможно, простой int) приводит к путанице. GCC выдавал ошибки (потому что компилирую с -Werror): x.c:2:10: error: multi-character character constant [-Werror=multichar] и x.c:2:10: error: overflow in implicit constant conversion [-Werror=overflow]   -  person Jonathan Leffler    schedule 08.01.2015


Ответы (5)


Вы используете восьмеричное или шестнадцатеричное число, потому что нет способа указать десятичные коды внутри символьного литерала или строкового литерала. Восьмеричный код преобладал в коде PDP-11. В наши дни, вероятно, имеет смысл использовать шестнадцатеричный формат, хотя '\0' более компактен, чем '\x0' (поэтому используйте '\0', когда вы завершаете строку нулем и т. д.).

Кроме того, имейте в виду, что "\x0ABad choice" не имеет того значения, которое вы могли бы ожидать, в то время как "\012007 wins", вероятно, имеет. (Разница в том, что шестнадцатеричный escape-код работает до тех пор, пока не встретит не шестнадцатеричную цифру, тогда как восьмеричный escape-код останавливается не более чем после 3 цифр. Чтобы получить ожидаемый результат, вам понадобится "\x0A" "Bad choice", используя «конкатенацию смежных строковых литералов».)

И это никак не связано с производительностью и очень мало связано с портативностью. Написание '\x41' или '\101' вместо 'A' — это способ уменьшить переносимость и читабельность вашего кода. Вы должны рассмотреть возможность использования escape-последовательностей только в том случае, если нет лучшего способа представить символ.

person Jonathan Leffler    schedule 08.01.2015
comment
Вы подразумеваете, что \012007 остановится после 3 цифр и будет эквивалентно \012 ? - person frogleaf; 08.01.2015
comment
Это строка из 9 символов, первый символ которой — '\012', также известный как control-L и обычно эквивалентный '\f' (form-feed); остаток "007 wins". Так что да, восьмеричные escape-последовательности останавливаются не более чем после 3 восьмеричных цифр, но шестнадцатеричные escape-последовательности останавливаются на первой нешестнадцатеричной цифре. - person Jonathan Leffler; 08.01.2015

Нет, это не имеет ничего общего с производительностью и портативностью. Это всего лишь один удобный способ определить символьные литералы и использовать их в строковых литералах специально для непечатаемых символов.

person Mohit Jain    schedule 08.01.2015

Это не имеет ничего общего с производительностью или портативностью. На самом деле никаких кодов вообще не нужно, вместо этого:

char c = 65;

Вы можете просто написать:

char c = 'A';

Но некоторые символы не так просто ввести, например. ASCII SOH, поэтому вы можете написать:

char c = 1; // SOH

Или любая другая форма, шестнадцатеричная, восьмеричная, в зависимости от ваших предпочтений.

person John Zwinck    schedule 08.01.2015

Это не имеет ничего общего ни с производительностью, ни с портативностью. Просто набор символов ASCII (как и его производные вплоть до UTF) организован в байтах и ​​битах. Например, 32 первых символа являются управляющими символами, 32 = 040 = 0x20, ASCII-код «A» — это 65 = 0101 = 0x41, а «a» — это 97 = 0141 = 0x61, ASCII-код «0» — это 48 = 060 = 0x30.

Не знаю, как вам, а мне '0x30' и 0x'41' легче запомнить и использовать в ручных операциях, чем 48 и 65.

Кстати, байт представляет ровно все значение от 0 до 255, то есть от 0 до 0xFF...

person Serge Ballesta    schedule 08.01.2015
comment
Спасибо, что указали, как ASCII выравнивает границы битов с наборами управляющих символов, цифр, строчных и прописных букв. Наиболее аккуратно он выравнивается с восьмеричным: коды меньше \100 в основном небуквенные, вторая половина которых в основном цифры. Коды выше \100 в основном состоят из букв, вторая половина которых в основном строчная. Управляющие символы соответствуют прописным буквам, просто игнорируя первую цифру 1 в верхнем регистре. - person lauir; 19.06.2020

Я не знал, что это работает.

Но у меня тут же возникла довольно полезная идея.

Представьте, что у вас мало памяти, и вы должны использовать систему разрешений, такую ​​как права доступа к папкам unix.

Допустим, есть 3 группы и для каждой группы 2 разных варианта, которые можно разрешить или запретить.

0 означает ни один из обоих вариантов,

1 означает, что разрешен первый вариант,

2 означает, что второй вариант разрешен и

3 означает, что оба разрешены.

Чтобы сохранить разрешения, вы можете сделать это так:

char* bar = "213"; // first group has allowed second option, second group has first option allowed and third has full acces.

Но у вас есть четырехбайтовое хранилище для этой информации.

Конечно, вы можете просто преобразовать это в десятичную запись. Но это менее читабельно.

Но теперь, когда я это знаю....

делает:

char bar = '\0213';

Это довольно читабельно, а также экономит память! Я люблю это :D

person dhein    schedule 08.01.2015