2016-08-25 2 views
-1
#include<stdio.h> 
main() 
{ 
printf("% % % %"); 
} 

Для вышеуказанной программы выход равен%%. Но почему? (Я использовал gcc-компилятор).Почему% печатается пополам в C?

+3

Вы можете компилировать с '-Wall -Wextra -Wpedantic'. – EOF

+3

Пожалуйста, прочитайте ссылку [printf] (http://en.cppreference.com/w/cpp/io/c/fprintf) о ее параметре 'format' – mvidelgauz

+0

@mvidelgauz. Лучше было бы ссылаться на сайт C, хотя , правильно? –

ответ

2

Это интересно. %% считается как %% каким-то образом, да. Должно быть в правилах разбора для форматов printf в библиотеке stdio. В общем случае «%» не является точно допустимой спецификацией формата. %% %% %% %% предоставит вам то, что вы хотите.

+0

Это библиотека, а не компилятор на работе здесь. – rici

+0

Совершенно верно, исправлено. – BenPen

5

Неопределенное поведение вызывается с использованием недопустимого спецификатора формата.

N1570 7.21.6.1 Функция fprintf говорит в описании % спецификатором преобразования:

Полная спецификация преобразования должна быть %%.

N1570 4. Соответствие говорит:

Если «» должен «» или «» не должны «» требование, которое появляется за пределами ограничений или выполнения-ограничение нарушается, то поведение не определено ,

Описание спецификатора преобразования % находится в разделе «Описание», а не в разделе ограничения или ограничения времени исполнения.

В реальной РЕАЛИЗАЦИИ, поведение системы кажется, что это:

  1. Читайте первый % и начать разбор Тендерного
  2. Read   и сохранить его как флаг
  3. Читать второй % и относиться к нему как % спецификатор преобразования
  4. Прочтите   после этого и распечатайте его, поскольку он не является частью Спецификатор
  5. Читать % % и работают как 1-3
+0

Ах, да, вы старое «неопределенное поведение». Интересно, как много зависит от этого. Предоставлены ли повышенные предупреждения выше этого? Это техническая ошибка времени выполнения, хотя статический анализ во время компиляции возможен в этом случае. – BenPen

+0

Я бы не попытался рационализировать это поведение, так как пробел не может быть флагом, модификатором, спецификатором. Это просто неопределенное поведение. – 2501

+0

@ 2501 Пробел - это флаг, который сообщает системе распечатать пробел в качестве знака для неотрицательных целых чисел. Например, '% d' является допустимым спецификатором формата. – MikeCAT

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