Чому знак специфіку (%) було обрано специфікатором формату для сімейства функцій printf?


27

Всім відомо, що, принаймні на C, ви використовуєте printfсімейство функцій для друку відформатованого рядка. І ці функції використовують знак відсотка ( %) для позначення початку специфікатора формату. Наприклад, %dзасоби для друку intта %uзасоби для друку unsigned int. Якщо ви не знайомі з тим, як printfфункціонують функції та формати заповнювачів, або вам просто потрібне оновлення, стаття у Вікіпедії - це гарне місце для початку.

Моє запитання: чи є особливо переконлива причина, чому це було спочатку або його слід обирати в майбутньому як специфікатора формату?

Очевидно, рішення було прийняте дуже давно (дуже ймовірно, що для попередника навіть мови С), і з тих пір воно було більш-менш "стандартним" (не тільки на С, але й у величезному масиві інших мов, які у різній мірі прийняли його синтаксис), тому далеко не пізно колись змінюватися. Але мені все одно цікаво, чи хтось має розуміння того, чому цей вибір, можливо, був зроблений в першу чергу, і чи все ще має сенс вибір, якщо розробляти нову мову з подібною функціональністю.

Наприклад, за допомогою C # (та іншого сімейства мов .NET) Microsoft прийняла дещо інше рішення щодо роботи функцій форматування рядків. Хоча певна ступінь безпеки типу може бути забезпечена (на відміну від реалізації printfв C), і тому не потрібно включати вказівку типу відповідного параметра, вони вирішили використовувати нульові індексовані пари фігурних дужок ( {}) як специфікатори формату, наприклад:

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}і {u}, але це не так. У когось є якісь думки щодо того, чи має це рішення сенс ретроспективним і чи слід за ним виконувати нові реалізації?

Очевидно, що немає жодного символу, який не міг би бути вибраним, щоб він міг бути включений у саму рядок, але ця проблема досить добре вирішена вже за допомогою двох з них. Які ще міркування є актуальними?


5
Проблема, що виходить, не вирішується за допомогою двох символів. Це просто означає, що у вас є ще один персонаж, який має втекти.
JJJ

2
Мені цікаво. Звичайно, це можна було б використовувати {u}замість, %uале чи матиме це якусь істотну перевагу? Це здається значною мірою довільним вибором.
CB Bailey

12
@JarrodRoberson, так що ви говорите, що вони навмисно вибрали {}синтаксис, щоб люди, які навчаються C #, не почали вивчати нічого іншого? Мені дуже важко повірити, що це було головною, навіть якщо такою, частиною їх дизайнерського рішення. Чи можете ви якось створити резервну копію своєї заяви?
вівторок

6
Цікаво, що Python відмовився від (набагато вищої форми) %форматування на користь чогось подібного до {}форматування .NET, оскільки останній пропонує більшу гнучкість.
Конрад Рудольф

3
Чому небо синє, і чому слово "синій" названо блакитним? Вони повинні були щось вибрати.

Відповіді:


12

Як зазначає @Secure, printfфункція C надихається функцією BCPL writef. І якщо ви подивитеся на сторінку wikipedia для BCPL , на ній є приклад, який показує, що BCPL writefтакож використовувався %для введення специфікатора формату.

Тож ми можемо зробити висновок, що C використовується %або тому, що зробив BCPL, або з тих же причин, що і BCPL. Моє відчуття кишки полягає в тому, що це був просто %один з найменш використовуваних символів ASCII ... або так вважали автори. Цілком ймовірно, що вони не витратили багато часу на зважування різних альтернатив. У той час і BCPL, і C були незрозумілими мовами, і автори, швидше за все, мали справу з більш важливими справами.

Однак у роботах є незначний розгалужувач. Хоча C був натхненний BCPL, не зовсім зрозуміло, запозичила ли бібліотека C BCPL введення-виведення або навпаки. Я злегка згадую, що бібліотеки вводу-виводу BCPL пройшли процес еволюції приблизно про час, коли до мови додали оператора індексації байтів інфіксації. (Насправді, я думаю, я знаю, хто про це знав би.)


3
"Насправді, я думаю, я знаю, хто би знав про це" ... і? ... і? .. Не просто залишайте нас із вішалкою ...
Mawg

2
@Mawg - Брайан Найт, мабуть, міг би. Ймовірно, Йен Вілсон. Мартін Річардс точно би. HTH.
Стівен C

6

Запис у Вікіпедії не містить великої кількості історичної інформації, не специфічної для printf, але загалом для втечі символів.

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

Ранні посилання на термін "рятувальний персонаж" можна знайти в технічних виданнях Боб Бемера IBM. Мабуть, саме він винайшов цей механізм під час своєї роботи над набором символів ASCII.

Я здогадуюсь: зворотний проріз вже використовувався для рядкових літералів, а для рядків формату потрібен інший символ. Швидше за все, вони обрали персонажа з припущеною найменшою частотою звичайного використання та появи.

До речі, ще одна пов’язана стаття там пов’язана з терміном, про який я чув раніше:

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

У статті для статті printfє ще кілька інформаційних фрагментів, але не про причини.

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

Різноманітний printf C має початок у функції запису BCPL.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.