Здесь много чего происходит. Как говорили другие, printf()
ничего не знает о выражении 5+"Good Morning"
. Значение этого выражения определяется языком C.
Сначала a+b
совпадает с b+a
, поэтому 5+"Good Morning"
совпадает с "Good Morning"+5
.
Теперь тип "Good Morning"
(то есть строковый литерал) является "массивом char
". В частности, "Good Morning"
представляет собой массив из 13 символов (12 «обычных» символов, за которыми следует 0
). При использовании в большинстве выражений тип массива в C «распадается» на указатель на его первый элемент, и двоичное сложение является одним из таких случаев. Все это означает, что в "Good Morning"+5
, "Good Morning"
распадается на указатель на свой первый элемент, которым является символ G
.
Вот как выглядит память:
0 1 2 3 4 5 6 7 8 9 0 1 2
+---+---+---+---+---+---+---+---+---+---+---+---+---+
| G | o | o | d | | M | o | r | n | i | n | g | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+
Значение адреса G
плюс 5 является указателем, который указывает на 5 местоположений от G
выше, что составляет M
. Итак, printf()
получает адрес по адресу M
. printf()
печатает, пока не найдет 0
. Следовательно, вы видите Morning
как вывод.