Не могу понять смысл этого фрагмента C - PullRequest
0 голосов
/ 07 января 2011

В следующем коде поведение не определено?

#include<stdio.h>
int main()
{
printf(7+"%c","sundaram");  
}

Его печать "арам".Не могу понять, как.

Ответы [ 3 ]

6 голосов
/ 07 января 2011

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

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

Данные вашей программы располагаются в памяти следующим образом:

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

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

2 голосов
/ 07 января 2011

Как уже отмечали другие, поведение равно undefined , потому что выражение 7+"%c" не указывает на элемент в массиве или один за концом массива. См. Онлайн-стандарт языка C, черновик n1256 , & sect; 6.5.6 и пункт; 8 для деталей.

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

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

«% c» начинается с 0x00008000, а «sundaram» начинается с 0x000080003.

Когда вы звоните

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

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

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

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

2 голосов
/ 07 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...