Perché è stato scelto il segno di percentuale (%) come identificatore di formato per la famiglia di funzioni printf?


27

Tutti sanno che, almeno in C, si utilizza la printffamiglia di funzioni per stampare una stringa formattata. E queste funzioni usano un segno di percentuale ( %) per indicare l'inizio di un identificatore di formato. Ad esempio, %dsignifica stampare un inte %usignifica stampare un unsigned int. Se non hai familiarità con il printffunzionamento della funzione e del formato dei segnaposto o hai semplicemente bisogno di un aggiornamento, l'articolo di Wikipedia è un buon punto di partenza.

La mia domanda è: esiste un motivo particolarmente convincente per cui questo è stato originariamente o dovrebbe essere scelto in futuro come identificatore del formato?

Ovviamente la decisione è stata presa molto tempo fa (molto probabilmente per un predecessore anche del linguaggio C), ed è stata più o meno "standard" da allora (non solo in C, ma anche in una vasta gamma di altre lingue che hanno adottato la sua sintassi a vari livelli), quindi è troppo tardi per cambiare mai. Ma sono ancora curioso di sapere se qualcuno ha qualche idea sul perché questa scelta potrebbe essere stata fatta in primo luogo e se ha ancora senso come scelta se si sta progettando un nuovo linguaggio con funzionalità simili.

Ad esempio, con C # (e l'altra famiglia di linguaggi .NET), Microsoft ha preso una decisione leggermente diversa per quanto riguarda il funzionamento delle funzioni di formattazione delle stringhe. Sebbene un certo grado di sicurezza del tipo possa essere applicato lì (diversamente dall'implementazione di printfin C), e quindi non è necessario includere un'indicazione del tipo del parametro corrispondente, hanno deciso di utilizzare coppie di parentesi graffe a indice zero ( {}) come identificatori di formato, in questo modo:

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 documentazione per il String.Formatmetodo contiene ulteriori informazioni, così come questo articolo sulla formattazione composita in generale , ma i dettagli esatti sono piuttosto irrilevanti. Il punto è semplicemente che hanno abbandonato la pratica di lunga data dell'uso %per indicare l'inizio di un identificatore di formato. Il linguaggio C avrebbe potuto facilmente essere usato {d}e {u}, ma non lo fece. Qualcuno ha qualche idea sul perché, se questa decisione ha un senso a posteriori e se le nuove implementazioni dovrebbero seguirla?

Ovviamente non c'è nessun personaggio che possa essere scelto che non debba essere evitato in modo che possa essere incluso nella stringa stessa, ma quel problema è già abbastanza ben risolto semplicemente usando due di essi. Quali altre considerazioni sono rilevanti?


5
Il problema di fuga non viene risolto utilizzando due caratteri. Significa solo che hai un personaggio in più per scappare.
JJJ il

2
Io sono curioso. Certamente, sarebbe possibile utilizzare {u}invece di %uma avrebbe qualche vantaggio significativo? Sembra una scelta in gran parte arbitraria.
CB Bailey,

12
@JarrodRoberson, quindi stai dicendo che hanno scelto deliberatamente la {}sintassi in modo che le persone che imparano C # non inizino a imparare nient'altro? Trovo molto difficile credere che sia stata una parte importante, se non addirittura una, della loro decisione di progettazione. Puoi fare il backup della tua dichiarazione in qualche modo?
stijn

6
È interessante notare che Python ha abbandonato (una forma molto superiore di) %formattazione a favore di qualcosa di simile alla {}formattazione di .NET perché quest'ultima offre maggiore flessibilità.
Konrad Rudolph,

3
Perché il cielo è blu e perché la parola "blu" si chiama blu? Dovevano scegliere qualcosa.

Risposte:


12

Come osserva @Secure, la printffunzione di C si ispira alla writeffunzione di BCPL . E se guardi la pagina di Wikipedia per BCPL , ha un esempio che mostra che BCPL ha writefanche usato %per introdurre un identificatore di formato.

Quindi possiamo dedurre che C ha usato %o perché BCPL lo ha fatto, o per gli stessi motivi che ha fatto BCPL. La mia sensazione è che fosse semplicemente %uno dei caratteri ASCII meno comunemente usati ... o almeno così pensavano gli autori. È anche probabile che non abbiano trascorso molto tempo a valutare le varie alternative. All'epoca, sia BCPL che C erano lingue oscure, e gli autori avevano molto probabilmente cose più importanti da affrontare.

Tuttavia, c'è una chiave minore nelle opere. Sebbene C sia stato ispirato da BCPL, non è del tutto chiaro se la C abbia preso in prestito le librerie I / O BCPL o viceversa. Ricordo vagamente che le librerie I / O di BCPL hanno attraversato un processo di evoluzione nel momento in cui l'operatore di indicizzazione dei byte infissi è stato aggiunto al linguaggio. (In realtà, penso di sapere chi lo saprebbe.)


3
"In realtà, penso di sapere chi lo saprebbe" ... e? ? ... e .. Non appena ci lascia con un cliff-hanger ...
Mawg

2
@Mawg - Brian Knight probabilmente lo farebbe. Ian Wilson probabilmente lo farebbe. Martin Richards lo farebbe sicuramente. HTH.
Stephen C,

6

La voce di Wikipedia non contiene molte informazioni storiche, non specifiche printf, ma per sfuggire ai personaggi in generale.

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

I primi riferimenti al termine "carattere di fuga" si trovano nelle pubblicazioni tecniche IBM di Bob Bemer. Apparentemente, è lui che ha inventato questo meccanismo, durante il suo lavoro sul set di caratteri ASCII.

La mia ipotesi è: la barra rovesciata era già utilizzata per i letterali di stringa e per le stringhe di formato era necessario un altro carattere. Molto probabilmente hanno scelto il personaggio con la presunta minima frequenza di normale utilizzo e occorrenza.

A proposito, un altro articolo correlato è collegato lì con un termine che non ho mai sentito prima:

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

L'articolo per printfcontiene alcuni frammenti di informazioni, ma non sui motivi.

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

La stampa variadica di C ha le sue origini nella funzione writef di BCPL.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.