Как интерпретируется оператор printf? - PullRequest
9 голосов
/ 26 июля 2010

Как следующая строка интерпретируется компилятором GCC:

printf("HELLO");  

Я хочу знать это, потому что когда я запускаю следующую программу:

main()  
{  
    printf(5+"Good Morning");  
}  

Программа печатает:

Morning

Почему компилятор начинает печать с шестого символа?

Ответы [ 5 ]

25 голосов
/ 26 июля 2010

Это артефакт C-указателя-арифметика;printf - просто красная сельдь.

Тип строкового литерала (например, "Good morning ") - const char *. Ваш код эквивалентен:

const char *p = "Good morning";
p = p + 5;
printf(p);

Добавлениеуказатель и целое число создают указатель на 5-й элемент в последовательности.

22 голосов
/ 26 июля 2010

Здесь много чего происходит. Как говорили другие, 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 как вывод.

7 голосов
/ 26 июля 2010

Is - это то же самое, что и запись

char *ptr="Good Morning";

, за которой следует

printf( ptr + 5 );

, то есть &ptr[5] этот адрес указывает на "Утро";

Добавлениецелое число n для указателя приводит к адресу ptr + n * sizeof (тип)

4 голосов
/ 26 июля 2010

Потому что "Good Morning" - это указатель на строку (фактически на ее первый байт), а добавление 5 к этому указателю дает указатель на 5-й символ.Строки C заканчиваются нулем, поэтому в любом случае printf выполняется до тех пор, пока не встретится с нулем в конце.

3 голосов
/ 26 июля 2010

Он увеличивает входной указатель на 5 байтов и, следовательно, пропускает слово «Хорошо».

Это арифметика указателя в C.

Предположим, что базовый указатель строки «Доброе утро» равен p, а 5 + p = p + 5 и указывает на букву M.

Следовательно, входные данные для printf - это указатель от буквы M.

...