2011-01-07 5 views

ответ

2

Как было указано другими, поведение не определено, поскольку выражение 7+"%c" не указывает на элемент внутри массива или один за концом массива. См. Стандарт онлайн-языка C, проект n1256, § 6.5.6 для деталей.

По совпадению ваши строки раскладывают в памяти, как это (используя воображаемую начальный адрес):

Address   0x00 0x01 0x02 0x03 
-------   ---------------------- 
0x00008000  '%' 'c' 0  's' 
0x00008004  'u' 'n' 'd' 'a' 
0x00008008  'r' 'a' 'm' 0 

«% С» начинается с 0x00008000 и «сундарам» начинается в 0x000080003.

При вызове

printf(7+"%c", "sundaram"); 

выражение массив «% С» преобразуется из типа char [3] к char *, и его значение является адресом первого элемента в массиве, или 0x00008000. Таким образом, выражение 7+"%c" оценивает значение 7 + 0x00008000 или 0x00008007. Строка, начинающаяся с 0x00008007, - «aram».

Поскольку «aram» не содержит спецификаторов преобразования, второй аргумент («sundaram», который оценивается как 0x00008003) оценивается, но в противном случае игнорируется (§ 7.19.6.1, ¶ 2).

Поскольку поведение не определено, любой результат возможен; этот конкретный результат не гарантированно произойдет с другим компилятором или с разными настройками компилятора.

6

Это неопределенное поведение.

Строковый литерал в C является указателем на блок предварительно инициализированной памяти.
По совпадению, ваши два строковых литерала занимают смежные блоки памяти.
Когда вы добавляете 7 к указателю на первый литерал, вы в конечном итоге указываете на середину следующего литерала. Данные

вашей программы расположена в памяти, как это:

 
     %c\0sundaram\0 
     |  | 
"%c" --^  | 
7 + "%c" ------^ 

Таким образом, вы в конечном итоге вызова printf с двумя указателями в ту же строку ("adam", "sundadam") и без спецификаторов формата.

+0

Спасибо. Но почему он не рассматривает «% c» как спецификатор формата? если мы заменим 7 на 0, он выдает предупреждение, и на выходе ничего не отображается, когда он должен показывать «% c» – Daud

+1

Потому что, когда он смотрит на последовательные символы в памяти, начиная с 7, где «% c», он никогда видит «% c». –

+0

@Duad: Вы передаете ему указатель на '' adam '', а не ''% c ". – SLaks

2

Поведение не определено. Так получилось, что данные хранятся в памяти следующим образом: «% c \ 0sundaram \ 0», и вы получаете часть строки «sundaram» в качестве аргумента строки форматирования (при отсутствии спецификаторов формата в оставшейся строке формата аргументы printf игнорируются).

+0

Спасибо.Вы сказали «в отсутствие спецификаторов формата .....» Но есть спецификатор формата. Нет? – Daud

+0

Спецификатора формата для printf не существует. Эффект неопределенного поведения в вашем случае передает «aram» для printf как строку формата, которая не имеет спецификаторов формата. – zeuxcg

+0

Еще раз спасибо. я понял – Daud

Смежные вопросы