printf(&unix["\021C%set"],(unix)["Chb"]+"Trick"-0X67);
Это дает результат как «Крикет». Но я не могу понять, почему? http://ideone.com/fTEAHGЧто будет выводить следующее выражение и почему?
printf(&unix["\021C%set"],(unix)["Chb"]+"Trick"-0X67);
Это дает результат как «Крикет». Но я не могу понять, почему? http://ideone.com/fTEAHGЧто будет выводить следующее выражение и почему?
unix
является predefined macro indicating it's a Unix-like system.
В C index[array]
идентичен array[index]
. Как объясняются MSDN:
Обычно значение, представленное постфикса-выражение является значением указателя, такими как идентификатор массива, а выражение является интегральным значением (в том числе перечисленных типов). Однако все, что требуется синтаксически, состоит в том, что одно из выражений имеет тип указателя, а другое - целочисленного типа. Таким образом, интегральное значение может быть в позиции postfix-expression, а значение указателя может находиться в скобках в позиции выражения или индекса.
Так
printf(&unix["\021C%set"],(unix)["Chb"]+"Trick"-0X67);
переводит к
printf(&"(\021C%set"[1]),"Chb"[1]+"Trick"-0X67);
&("\021C%set"[1])
принимает адрес первого элемента "\ 021C% набора", что эквивалентно принимает адрес «C% set "(из-за арифметики C-указателя). Упрощение, что, и изменить некоторые операнды:
printf("C%set","Trick"+"Chb"[1]-0X67);
"Chb"[1]
является 'h'
, что является значением ASCII, 0x68, поэтому "Chb"[1]-0X67
равно 1, и это "Trick"+1
"rick"
(из-за C арифметики указателей). Таким образом, код упрощается далее до
printf("C%set","rick");
который печатает «Крикет».
Можете ли вы пояснить, почему '& (" \ 021C% set "[1])' является адресом '' C% set "'? Я не полностью понял ваши объяснения. –
@ DanielKleinstein - C строк - это массивы символов. Итак, '' \ 021C% set "[1]' означает элемент 1 массива "\ 021C% set". Элемент 1 является «C» (поскольку элемент 0 равен «\ 021»), поэтому & («\ 021C% set» [1]) является адресом «C» и адресом «C% set». –
Что означает '\ 021'? Я думал, что это означает, что нулевой символ следует за 2, а затем 1. –
Ну, unix
1 в этой реализации. a[b]
что-то вроде *(a+b)
, и a+b
- это что-то вроде b+a
, поэтому &unix["\021C%set"]
что-то вроде &(*("\021C%set"+1))
. Поскольку &(*(c))
более или менее c
, это получает вас "\021C%set"+1
, который является указателем на второй символ, поэтому только "C%set"
, который является строкой формата для «C», за которой следует строка, а затем «et». \021
- восьмеричный побег (длиной от 1 до 3 восьмеричных цифр, однако много действительных), поэтому он считается только одним символом.
Далее мы имеем (unix)["Chb"]
, что по тем же причинам, является такой же, как «ЦГБ» [1], который будет ИНТ значение «ч» характер, что в ASCII является 104. С другой стороны, 0X67
составляет 103. Таким образом, у нас есть 104+"Trick"-103
, или "Trick"+1
. Это та же самая арифметика указателя на строковой литературе, которая используется на левой стороне, и она получает вас «рик».
Таким образом, мы остались с:
printf("C%set", "rick");
который печатает "стог" между "C" и "ЕТ" (Cricket).
Близко связано: http://stackoverflow.com/q/19210935/827263 –