Восьмеричное представление внутри строки в C

В заданной программе:

int main() {
  char *p = "\0777";
  printf("%d %d %d\n",p[0],p[1],p[2]);
  printf("--%c-- --%c-- --%c--\n",p[0],p[1],p[2]);
  return 0;  
}

Он показывает вывод как:

63 55 0
--?-- --7-- ----

Я могу понять, что он преобразует первые два символа после \0 (\077) из восьмеричной в десятичную, но может ли кто-нибудь объяснить мне, почему 2 символа, почему не 1 или 3 или любой другой?

Пожалуйста, объясните логику этого.


person r.bhardwaj    schedule 05.08.2012    source источник
comment
Я полагаю, что ваш реальный код имеет char *p = "\7777"; без 0 впереди.   -  person pmg    schedule 05.08.2012


Ответы (2)


char *p = "\07777";

Здесь строковый литерал, назначенный указателю на char.

"\07777"

В этой строке используется буквальная восьмеричная escape-последовательность, поэтому первые три цифры представляют восьмеричное число. Потому что правила для восьмеричной escape-последовательности следующие:

В восьмеричной управляющей последовательности можно использовать только цифры от 0 до 7. Восьмеричные escape-последовательности никогда не могут быть длиннее трех цифр и заканчиваются первым символом, который не является восьмеричной цифрой. Хотя вам не обязательно использовать все три цифры, вы должны использовать хотя бы одну. Например, восьмеричное представление: \10 для символа возврата ASCII и \101 для буквы A, как указано в диаграмме ASCII.

SO ваш строковый литерал хранится в памяти, например

1-й байт как восьмеричное число 077, которое представляет собой не что иное, как 63 в десятичном виде и '?' в характере

2-й и 3-й байты как символы «7» и «7» соответственно

и завершающий символ '\0' в конце.

так что ваш ответ, как и ожидалось, 1-й, 2-й, 3-й байт строкового литерала.

для получения дополнительных объяснений вы можете посетить этот веб-сайт

http://msdn.microsoft.com/en-us/library/edsza5ck.aspx

person rajesh6115    schedule 05.08.2012
comment
эта ссылка дает вам больше информации об управляющих последовательностях c0x.coding-guidelines.com/6.4.4.4. html - person rajesh6115; 05.08.2012
comment
тогда в чем ваш вопрос. Если вы четко упомянете, то только хороший ответ вы можете получить. - person rajesh6115; 05.08.2012
comment
чтобы быть более точным, восьмеричные числа должны быть в диапазоне от \000 до \377, потому что они будут храниться в 1 байте, а после \377 будет отображаться предупреждение: восьмеричная escape-последовательность вне диапазона. - person r.bhardwaj; 06.08.2012
comment
да, восьмеричные escape-последовательности могут быть максимальными до \377, но если вы укажете \378, то \37 - это ваше восьмеричное число, а 8 - это символ (то есть максимум 3 символа, если все они находятся в диапазоне от 0 до 7). Вы понимаете эту концепцию или не? - person rajesh6115; 06.08.2012

Именно так язык определяет восьмеричные управляющие последовательности.

Восьмеричная escape-последовательность, которая может быть частью символьной константы или строкового литерала, состоит из \, за которым следуют ровно 1, 2 или 3 восьмеричных цифры ('0' .. '7').

В "\07777" за обратной косой чертой следуют 3 восьмеричных цифры (0, 7, 7), которые представляют символ со значением 077 в восьмеричном или 63 в десятичном. В ASCII или производной от ASCII кодировке это знак вопроса '?'.

Таким образом, литерал представляет собой строку длиной 3, состоящую из '?', '7', '7'.

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

63 55 55
--?-- --7-- --7--

Если я изменю объявление p на

char *p = "\0777";

Я получаю результат, который вы описываете. Обратите внимание, что последний ---- на самом деле состоит из двух дефисов, за которыми следует нулевой символ, за которым следуют два дефиса. Если вы работаете в Unix-подобной системе, попробуйте направить вывод программы через cat -v или cat -A.

Когда вы публикуете код, очень важно копировать и вставлять его, а не перепечатывать.

(И вам не хватает #include <stdio.h> вверху.)

person Keith Thompson    schedule 05.08.2012