Pourquoi le signe de pourcentage (%) a-t-il été choisi comme spécificateur de format pour la famille de fonctions printf?

27

Tout le monde sait qu'au moins en C, vous utilisez la printffamille de fonctions pour imprimer une chaîne formatée. Et ces fonctions utilisent un signe de pourcentage ( %) pour indiquer le début d'un spécificateur de format. Par exemple, %dsignifie imprimer un intet %usignifie imprimer un unsigned int. Si vous n'êtes pas familier avec le printffonctionnement des espaces réservés de fonction et de format, ou si vous avez simplement besoin d'un rafraîchissement, l'article Wikipedia est un bon point de départ.

Ma question est la suivante: y a-t-il une raison particulièrement convaincante pour laquelle cela a été initialement ou devrait être choisi à l'avenir comme spécificateur de format?

De toute évidence, la décision a été prise il y a longtemps (très probablement pour un prédécesseur même du langage C), et elle a été plus ou moins "standard" depuis lors (non seulement en C, mais aussi dans une vaste gamme d'autres langages qui ont adopté sa syntaxe à des degrés divers), il est donc beaucoup trop tard pour changer. Mais je suis toujours curieux de savoir si quelqu'un a une idée de la raison pour laquelle ce choix a pu être fait en premier lieu, et s'il est toujours logique de choisir si l'on conçoit un nouveau langage avec des fonctionnalités similaires.

Par exemple, avec C # (et l'autre famille de langages .NET), Microsoft a pris une décision légèrement différente concernant le fonctionnement des fonctions de formatage de chaînes. Bien qu'un certain degré de sécurité de type puisse y être appliqué (contrairement à l'implémentation de printfen C), et qu'il n'est donc pas nécessaire d'inclure une indication du type du paramètre correspondant, ils ont décidé d'utiliser des paires d'accolades bouclées à index zéro ( {}) comme spécificateurs de format, comme ceci:

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.

La documentation de la String.Formatméthode contient plus d'informations, tout comme cet article sur la mise en forme composite en général , mais les détails exacts sont plutôt sans importance. Le fait est simplement qu'ils ont abandonné la pratique de longue date d'utiliser %pour indiquer le début d'un spécificateur de format. Le langage C aurait pu facilement être utilisé {d}et {u}, mais il ne l'a pas fait. Quelqu'un a-t-il une idée de pourquoi, si cette décision a un sens rétrospectivement et si de nouvelles implémentations devraient la suivre?

Évidemment, il n'y a aucun caractère qui pourrait être choisi qui ne devrait pas être échappable pour qu'il puisse être inclus dans la chaîne elle-même, mais ce problème est déjà assez bien résolu en utilisant simplement deux d'entre eux. Quelles autres considérations sont pertinentes?

Cody Grey
la source
5
Le problème d'échappement n'est pas résolu en utilisant deux caractères. Cela signifie simplement que vous avez encore un personnage à échapper.
JJJ
2
Je suis curieux. Certes, il serait possible d'utiliser à la {u}place %umais aurait-il un avantage significatif? Cela semble être un choix largement arbitraire.
CB Bailey
12
@JarrodRoberson donc vous dites qu'ils ont délibérément choisi la {}syntaxe pour que les gens qui apprennent le C # ne commencent pas à apprendre autre chose? Je trouve très difficile de croire que c'était une partie importante, voire aucune, de leur décision de conception. Pouvez-vous sauvegarder votre relevé d'une manière ou d'une autre?
stijn
6
Fait intéressant, Python a abandonné (une forme bien supérieure de) %formatage au profit de quelque chose qui s'apparente au {}formatage de .NET car ce dernier offre plus de flexibilité.
Konrad Rudolph
3
Pourquoi le ciel est-il bleu et pourquoi le mot "bleu" est-il nommé bleu? Ils devaient choisir quelque chose.

Réponses:

12

Comme le note @Secure, la printffonction de C est inspirée de la writeffonction de BCPL . Et si vous regardez la page wikipedia de BCPL , elle contient un exemple qui montre que BCPL a writefégalement utilisé %pour introduire un spécificateur de format.

Nous pouvons donc en déduire que C a été utilisé %soit parce que BCPL l'a fait, soit pour les mêmes raisons que BCPL. Mon intuition est que c'est simplement l' %un des caractères ASCII les moins utilisés ... du moins c'est ce que les auteurs pensaient. Il est également probable qu'ils n'aient pas passé beaucoup de temps à peser les différentes alternatives. À l'époque, BCPL et C étaient des langages obscurs, et les auteurs avaient probablement des choses plus importantes à traiter.

Cependant, il y a une clé mineure dans les travaux. Alors que C a été inspiré par BCPL, il n'est pas tout à fait clair si les bibliothèques d'E / S BCPL ont emprunté C ou l'inverse. Je me souviens vaguement que les bibliothèques d'E / S de BCPL ont subi un processus d'évolution à peu près au moment où l'opérateur d'indexation des octets d'infixe a été ajouté au langage. (En fait, je pense que je sais qui serait au courant.)

Stephen C
la source
3
"En fait, je pense que je sais qui saurait ça" ... et? ... et? .. Ne nous laissez pas simplement avec un cintre ...
Mawg
2
@Mawg - Brian Knight le ferait probablement. Ian Wilson le ferait probablement. Martin Richards le ferait certainement. HTH.
Stephen C
6

L'entrée Wikipedia ne contient pas beaucoup d'informations historiques, non spécifiques à printf, mais permettant d'échapper aux personnages en général.

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

Une première référence au terme "caractère d'échappement" se trouve dans les publications techniques IBM de Bob Bemer. Apparemment, c'est lui qui a inventé ce mécanisme, lors de ses travaux sur le jeu de caractères ASCII.

Ma supposition est la suivante: la barre oblique inverse était déjà utilisée pour les littéraux de chaîne et un autre caractère était nécessaire pour les chaînes de format. Très probablement, ils ont choisi le personnage avec la fréquence la moins fréquente d'utilisation et d'occurrence normales.

BTW, un autre article connexe y est lié avec un terme que je n'ai jamais entendu auparavant:

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

L'article printfcontient des extraits d'informations supplémentaires, mais pas les raisons.

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

Printf variadic de C a ses origines dans la fonction writef de BCPL.

Garantir
la source