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

上記のプログラムの出力は%%です。しかし、なぜ? (私はgccコンパイラを使いました)。%がCで半分の数で印刷されるのはなぜですか?

+3

のように動作します。 – EOF

+3

'printf](http://en.cppreference.com/w/cpp/io/c/fprintf)参照とその' format'パラメータについての詳細は – mvidelgauz

+0

@mvidelgauz Cのサイトにリンクする方がいいでしょう。 、 右? –

答えて

2

これは興味深いです。 %%は何とか%%としてカウントされます。 stdioライブラリのprintf形式の解析ルールに含まれている必要があります。一般に、 "%"は正確なフォーマット指定ではありません。 %%%% %%%%はあなたが望むものを得るでしょう。

+0

これはライブラリであり、コンパイラではありませんここの職場で – rici

+0

まあまあです。 – BenPen

5

未定義の動作は無効な書式指定子を使用して呼び出されます。

N1570 7.21.6.1 fprintf関数は%変換指定子の説明で述べている:

完全な変換指定は%%されなければなりません。

N1570 4.適合性は言う:

制約または実行時制約の外に表示されます「」はなら「」または「」なければならない「」要件に違反している場合、動作は未定義です。

%の変換指定子の説明は、制約でも実行時制約セクションでもなく、「説明」セクションにあります。実際implementionで

、システムの動作は、このように思える:

  1. 最初%を読み、指定
  2. 読む  を解析を開始し、第二%を読み、それを扱うフラグ
  3. として保存します%変換指定子
  4. それ以降は  を読んで、それが一部ではないために印刷してください指定
  5. 読む% %とあなたは `-Wall -Wextra -Wpedantic`でコンパイルしたいかもしれません1-3
+0

ああ、はい、あなたが古い "未定義の動作"これに依存するコードの量は不思議です。上記の上昇した警告はこれを捕まえますか?この場合、コンパイル時の静的解析は可能ですが、技術的にはランタイムエラーです。 – BenPen

+0

空白はフラグ、修飾子、指定子になることはできないので、この振る舞いを合理化しようとはしません。それは単に定義されていない動作です。 – 2501

+0

@ 2501空白は、負でない整数の記号文字として空白を表示するようにシステムに指示するフラグです。例えば、 '%d'は有効な書式指定子です。 – MikeCAT

関連する問題