printfファミリの関数の形式指定子としてパーセント記号(%)が選択されたのはなぜですか?


27

少なくともCではprintf、関数ファミリを使用して書式設定された文字列を印刷することを誰もが知っています。また、これらの関数はパーセント記号%)を使用して、書式指定子の始まりを示します。例えば、%d印刷することを意味しint、そして%u手段印刷しますunsigned intprintf関数とフォーマットのプレースホルダーがどのように機能するのかよくわからない場合、または単にリフレッシャーが必要な場合は、Wikipediaの記事を参照してください

私の質問は、これが元々、または将来フォーマット指定子として選択されるべきである特に説得力のある理由がありますか?

明らかに、この決定はかなり前に行われ(C言語の前任者である可能性が非常に高い)、それ以降は多かれ少なかれ「標準」になっています(Cだけでなく、他の多くの言語でもさまざまな程度に構文を採用しているため)、変更するには遅すぎます。しかし、なぜこの選択​​が最初に行われたのか、同様の機能を備えた新しい言語を設計している場合の選択肢としてそれが理にかなっているのかについて誰かが洞察を持っているのであれば、私はまだ興味があります。

たとえば、C#(および他の.NET言語ファミリ)を使用して、Microsoftは文字列フォーマット関数の操作に関してわずかに異なる決定を下しました。そこにある程度のタイプセーフティを適用できますが(printfC の実装とは異なります)、したがって対応するパラメーターのタイプを示す必要はありませんが、中括弧({})のゼロインデックスペアを使用することにしました次のような形式指定子として:

string output = String.Format("In {0}, the temperature is {1} degrees Celsius.",
                              "Texas", 37);
Console.WriteLine(output);

// Output:
//     In Texas, the temperature is 37 degrees Celsius.

String.Format一般的な複合フォーマットに関するこの記事と同様に、メソッドのドキュメントには詳細情報が含まれていますが、正確な詳細はかなり重要ではありません。ポイントは%、フォーマット指定子の開始を示すために使用するという長年の慣行を放棄したということです。C言語は{d}and を簡単に使用でき{u}たはずですが、そうではありませんでした。誰が、なぜ、この決定が振り返って意味をなすか、そして新しい実装がそれに続くべきかどうかについての考えを持っていますか?

明らかに、文字列自体に含めることができるようにエスケープする必要のない文字を選択することはできませんが、その問題は、そのうちの2つを使用するだけで既に十分に解決されています。関連する他の考慮事項は何ですか?


5
エスケープの問題は、2文字を使用して解決されません。エスケープするキャラクターがもう1つあるということです。
-JJJ

2
気になります。確かに、{u}代わりに使用することは可能%uですが、大きな利点はありますか?それは大部分がarbitrary意的な選択のようです。
CBベイリー

12
@JarrodRobersonですから、{}C#を学習している人が他のことを何も学習しないように、意図的に構文を選択していると言っていますか?それが彼らの設計決定の重要な部分であったとしても、それを信じることは非常に難しいと思います。なんとかして声明をバックアップできますか?
stijn

6
興味深いことに、Pythonは(はるかに優れた形式の)%フォーマットを放棄し、.NETの{}フォーマットに似たものを支持しました。後者の方が柔軟性が高いためです。
コンラッドルドルフ

3
なぜ空は青で、なぜ「青」という言葉の名前は青ですか?彼らは何かを選ばなければなりませんでした。

回答:


12

@Secureが指摘しているように、Cのprintf機能はBCPLのwritef機能に触発されています。BCPLのウィキペディアのページを見ると、BCPLがフォーマット指定子の導入にwritefも使用%されたことを示す例があります。

したがって%、BCPLが使用したため、またはBCPLが使用したのと同じ理由で、Cが使用したと推測できます。私の直感では、それは単に%最も一般的に使用されていないASCII文字の1つであるということです...または著者たちはそう考えました。また、彼らがさまざまな代替案を検討するのに多くの時間を費やさなかった可能性もあります。当時、BCPLとCはどちらも曖昧な言語であり、著者はおそらく、対処すべきより重要なものを持っていました。

しかし、作品にはマイナーなスパナがいます。CはBCPLに触発されましたが、CがBCPL I / Oライブラリを借りたのか、それとも他の方法を借りたのかは完全には明らかではありません。BCPLのI / Oライブラリは、挿入バイトインデックス演算子が言語に追加された頃に進化プロセスを経たことをぼんやりと思い出します。(実際、私は誰がそれについて知っていると思います。)


3
「実際、誰がそのことを知っていると思いますか」と...?... and?..崖にハンガーを置いて行くだけではありません...
Mawg

2
@Mawg-ブライアンナイトはおそらくそうでしょう。イアン・ウィルソンはおそらくそうするでしょう。マーティン・リチャーズは間違いなくそうだ。HTH。
スティーブンC

6

ウィキペディアのエントリには、特定の履歴情報は含まれていませんがprintf、一般的なキャラクターをエスケープします。

http://en.wikipedia.org/wiki/Escape_character

「エスケープ文字」という用語への初期の言及は、Bob BemerのIBM技術出版物にあります。どうやら、ASCII文字セットの作業中にこのメカニズムを発明したのは彼です。

私の推測では、バックスラッシュは文字列リテラルにすでに使用されており、フォーマット文字列には別の文字が必要でした。ほとんどの場合、彼らは通常の使用と発生の頻度が最も少ないと想定されるキャラクターを選択しました。

ところで、別の関連記事は、私が前に聞いたことのない用語にリンクされています

http://en.wikipedia.org/wiki/Leaning_toothpick_syndrome

の記事にprintfはいくつかの情報スニペットがありますが、その理由についてではありません。

http://en.wikipedia.org/wiki/Printf

Cの可変引数printfは、BCPLのwritef関数に由来しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.