2017-02-17 8 views
2

В последнее время я пытаюсь понять подробный инструмент printf в C, . Я понимаю использование va_start, va_arg и va_end, , но один вопрос, который я всегда не могу понять, заключается в том, как printf получает размер каждого параметра в хотя он знает формат вывода (% d,% c и т. д.). Приведу один пример, чтобы показать мой вопрос более наглядно:Как функция printf в C получает размер каждого параметра в списке параметров переменных?

int a = 27; 
char b = 19; 
printf("%d, %c", a, b); 

подробное орудие Printf, что я знаю, что: шаг 1: он получает указатель на начало переменных параметров с помощью макросов va_start (арг, формат), формат - указатель на указатель на нижнюю строку «% d,% c», args - это указатель на начало переменных параметров, расположенных в стеке; Шаг 2: он получает значение каждого параметра с помощью макросов va_arg (args, int), а затем выводит параметры в соответствии со строкой формата; Шаг 3: используя va_end (args), очистите указатель args;

Критическая точка, которую я не могу понять, заключается в том, что когда функция хочет вывести значение a, почему она может знать, используя «int» в качестве вторых параметров макросов va_arg? подробное выполнение макросов va_arg состоит в том, чтобы получить данные в соответствии с указателем args к стеку, длина получения данных зависит от вторых параметров, здесь это int, зачем он вводит «int» в va_arg, а не в «char» или «long int», какое условие позволяет ему вводить «int»? Условие является строкой формата? в приведенном выше примере, он не может получить размер a, зависит только от «% d».

Большое спасибо за ваше объяснение заранее.

+0

Знаете ли вы о концепции C по умолчанию для рекламных акций по умолчанию? Думаю, это недостающая часть головоломки. Дело в том, что передать символ 'char' трудно, как показано в коде. – unwind

ответ

2

... для вывода значения a, почему он может знать, используя «int» в качестве вторых параметров макросов va_arg?

Потому что вы так и сказали.

%d преобразование требует в int в качестве входных данных, так printf предполагает, что вы прошли правильный тип.

Если вы ошиблись (например, вы передадите символ для спецификатора преобразования %d), он сломается, и это ваша вина.

Соответствующий текст из моей локальной страницы руководства является:

Аргументы должны соответствовать (после преобразования типа) с спецификатор преобразования.

И this reference содержит подробную таблицу, описывающую необходимый тип аргумента для каждого спецификатора преобразования. Некоторые компиляторы или статические анализаторы могут предупредить вас, если ваши типы аргументов не соответствуют вашей строке формата, но в конечном итоге ваша ответственность заключается в правильном кодировании.

+0

Большое спасибо, с помощью вашего ответа, я могу понять это сейчас. – Ryan

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

  • Нет связанных вопросов^_^