printf () в c. Если он не обрабатывает входное значение как адрес - PullRequest
1 голос
/ 04 февраля 2011

Я только что видел подпись для printf.это int printf(const *f).Теперь, если я объявлю int i и сделаю следующее:

int i=5;
printf("%d",i);

, он отобразит правильное значение i.Мне интересно, почему это так?Поскольку printf принимает указатель, он не должен рассматривать значение i как адрес и печатать значение, сохраненное по этому адресу.

Обратите внимание, что printf("%d", &i) не работает.

Ответы [ 7 ]

4 голосов
/ 04 февраля 2011

printf() - это переменная функция . Это означает, что его первый аргумент указывает количество и тип оставшихся аргументов, которые должны быть извлечены из стека.

Первый аргумент - и единственный, на который не влияет переменная функция, - это строка и, следовательно, указатель (на массив char, если это имеет значение). Остальные аргументы обрабатываются по-разному и не перечислены в упомянутом вами упрощенном прототипе.

Кстати, вот полный прототип printf(), полученный из моего заголовка stdio.h:

extern int printf (const char *format, ...);
1 голос
/ 04 февраля 2011

Первый аргумент - это строка формата.Когда вы передаете строку в функцию, вы, по сути, передаете указатель.

(Кроме того, подпись на самом деле int printf(const char *, ...).)

0 голосов
/ 04 февраля 2011

Просто добавлю, что printf("%d", &i) действительно работает.Вместо того, чтобы печатать значение переменной i, он печатает адрес памяти, в котором хранится переменная (& обозначает отключение адреса).

0 голосов
/ 04 февраля 2011

Единственный параметр, необходимый для printf, - это строка формата, которая должна быть преобразована в const char *.Это не значит, что другие параметры должны быть указателями.printf на самом деле не знает о других параметрах, кроме как смотрит на строку формата.Он анализирует строку формата и ищет шаблоны, начинающиеся с%.В вашем случае он видит% d и говорит, что в стеке должен быть параметр int, поэтому он выходит и захватывает следующий параметр и интерпретирует его как int.Если вы не предоставите соответствующий параметр или параметр неправильного типа, он напечатает мусор.

0 голосов
/ 04 февраля 2011

Подпись printf НЕ int printf(const *f). Где вы взяли эту странную подпись?

Настоящая подпись printf - int printf(const char *, ...). Обратите внимание на ... в конце. Это ... обозначает переменные аргументы, которые вы передаете printf после первого аргумента. Первый аргумент - это формат ("%d" в вашем случае). Другие аргументы интерпретируются printf в соответствии с этим форматом. Вы указали %d в качестве формата, что означает, что следующий аргумент интерпретируется как значение int, а не как адрес.

0 голосов
/ 04 февраля 2011

Нет - printf просто получает 32-битное (или любое другое) значение, он не знает, какой тип вы думаете, что это.

0 голосов
/ 04 февраля 2011

printf(3) - это переменная функция . Он интерпретирует свои дополнительные аргументы из строки формата .

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