Por que o sinal de porcentagem (%) foi escolhido como o especificador de formato para a família de funções printf?

27

Todo mundo sabe que, pelo menos em C, você usa a printffamília de funções para imprimir uma string formatada. E essas funções usam um sinal de porcentagem ( %) para indicar o início de um especificador de formato. Por exemplo, %dsignifica imprimir um inte %usignifica imprimir um unsigned int. Se você não conhece o printffuncionamento dos marcadores de função e formato, ou simplesmente precisa de uma atualização, o artigo da Wikipedia é um bom ponto de partida.

Minha pergunta é: existe uma razão particularmente convincente pela qual isso foi originalmente ou deveria ser escolhido no futuro como o especificador de formato?

Obviamente, a decisão foi tomada há muito tempo (muito provavelmente para um predecessor até da linguagem C), e tem sido mais ou menos "padrão" desde então (não apenas em C, mas também em uma vasta gama de outras linguagens que adotaram sua sintaxe em vários graus), então é tarde demais para mudar. Mas ainda estou curioso se alguém tem alguma idéia sobre por que essa escolha pode ter sido feita em primeiro lugar, e se ainda faz sentido como a escolha se alguém está projetando um novo idioma com funcionalidade semelhante.

Por exemplo, com C # (e a outra família de linguagens .NET), a Microsoft tomou uma decisão ligeiramente diferente em relação à operação das funções de formatação de seqüência de caracteres. Embora possa ser imposto algum grau de segurança de tipo (diferente da implementação printfem C) e, portanto, não é necessário incluir uma indicação do tipo do parâmetro correspondente, eles decidiram usar pares de chaves com índice zero ( {}) como especificadores de formato, assim:

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.

A documentação para o String.Formatmétodo contém mais informações, assim como este artigo sobre formatação composta em geral , mas os detalhes exatos não são importantes. A questão é simplesmente que eles abandonaram a prática de longa data de usar %para indicar o início de um especificador de formato. A linguagem C poderia ter sido facilmente usada {d}e {u}, mas não. Alguém tem alguma opinião sobre por que, se essa decisão faz sentido em retrospecto e se novas implementações devem segui-la?

Obviamente, não há nenhum personagem que possa ser escolhido que não precise ser escapável para que possa ser incluído na própria string, mas esse problema já está bem resolvido usando apenas dois deles. Que outras considerações são relevantes?

Cody Gray
fonte
5
O problema de escape não é resolvido usando dois caracteres. Significa apenas que você tem mais um personagem para escapar.
JJJ
2
Estou curioso. Certamente, seria possível usar em {u}vez de, %umas teria alguma vantagem significativa? Parece uma escolha amplamente arbitrária.
CB Bailey
12
@JarrodRoberson, então você está dizendo que eles escolheram deliberadamente a {}sintaxe para que as pessoas que aprendem C # não começassem a aprender mais nada? Acho muito difícil acreditar que essa foi uma parte importante, se é que alguma, da sua decisão de design. Você pode fazer backup de sua declaração de alguma forma?
stijn
6
Curiosamente, o Python abandonou (uma forma muito superior) de %formatação em favor de algo semelhante à {}formatação do .NET, porque o último oferece mais flexibilidade.
Konrad Rudolph
3
Por que o céu é azul e por que a palavra "azul" é chamada de azul? Eles tiveram que escolher alguma coisa.

Respostas:

12

Como observa o @Secure, a printffunção de C é inspirada na writeffunção de BCPL . E se você olhar a página da Wikipedia sobre BCPL , há um exemplo que mostra que o BCPL writeftambém usou %para introduzir um especificador de formato.

Portanto, podemos inferir que C foi usado %porque o BCPL o fez, ou pelos mesmos motivos que o BCPL. Meu pressentimento é que era simplesmente %um dos caracteres ASCII menos usados ​​... ou assim pensavam os autores. Também é provável que eles não passassem muito tempo avaliando as várias alternativas. Na época, tanto o BCPL quanto o C eram linguagens obscuras, e os autores provavelmente tinham coisas mais importantes para lidar.

No entanto, existe uma pequena chave inglesa nos trabalhos. Embora o C tenha sido inspirado pelo BCPL, não está totalmente claro se o C emprestou as bibliotecas de E / S do BCPL ou o contrário. Lembro-me vagamente que as bibliotecas de E / S do BCPL passaram por um processo de evolução na época em que o operador de indexação de bytes infix foi adicionado à linguagem. (Na verdade, acho que sei quem saberia sobre isso.)

Stephen C
fonte
3
"Na verdade, acho que sei quem saberia sobre isso" ... e? ? ... e .. Não basta deixar-nos com um precipício-cabide ...
MAWG
2
@ Makg - Brian Knight provavelmente faria. Ian Wilson provavelmente faria. Martin Richards definitivamente faria. HTH.
Stephen C
6

A entrada da Wikipedia não contém muitas informações históricas, não específicas printf, mas para escapar de caracteres em geral.

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

A referência inicial ao termo "caractere de escape" é encontrada nas publicações técnicas da IBM de Bob Bemer. Aparentemente, foi ele quem inventou esse mecanismo, durante seu trabalho no conjunto de caracteres ASCII.

Meu palpite é: A barra invertida já foi usada para literais de strings e outro caractere foi necessário para as strings de formato. Muito provavelmente eles escolheram o personagem com a menor frequência presumida de uso e ocorrência normais.

BTW, outro artigo relacionado está vinculado a um termo que eu nunca ouvi antes:

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

O artigo para printftem mais alguns trechos de informações, mas não sobre os motivos.

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

A variável printf de C tem suas origens na função writef do BCPL.

Seguro
fonte