เหตุใดจึงเลือกเครื่องหมายเปอร์เซ็นต์ (%) เป็นตัวระบุรูปแบบสำหรับตระกูลของฟังก์ชั่น printf


27

ทุกคนรู้ว่าอย่างน้อยใน C คุณใช้printfตระกูลฟังก์ชันเพื่อพิมพ์สตริงที่จัดรูปแบบ และฟังก์ชั่นเหล่านี้ใช้เครื่องหมายเปอร์เซ็นต์ ( %) เพื่อระบุจุดเริ่มต้นของตัวระบุรูปแบบ ยกตัวอย่างเช่น%dหมายถึงการพิมพ์intและวิธีการในการพิมพ์%u unsigned intหากคุณไม่คุ้นเคยกับการprintfทำงานของตัวยึดตำแหน่งและการจัดรูปแบบหรือเพียงต้องการทบทวนบทความ Wikipediaเป็นจุดเริ่มต้นที่ดี

คำถามของฉันคือมีเหตุผลที่น่าสนใจเป็นพิเศษหรือไม่ว่าทำไมจึงควรเลือกใช้ตัวเลือกรูปแบบในอนาคตในอนาคต

เห็นได้ชัดว่าการตัดสินใจทำมานานแล้ว (น่าจะเป็นบรรพบุรุษของภาษา C) และมันก็เป็น "มาตรฐาน" มากขึ้นเรื่อย ๆ ตั้งแต่นั้นมา (ไม่เพียง แต่ใน C แต่ยังอยู่ในภาษาอื่นอีกมากมาย ได้ปรับใช้ไวยากรณ์กับองศาที่แตกต่างกัน) ดังนั้นมันจึงสายเกินไปที่จะเปลี่ยนแปลง แต่ฉันก็ยังสงสัยว่าใครมีความเข้าใจว่าทำไมตัวเลือกนี้อาจเกิดขึ้นตั้งแต่แรกและไม่ว่ามันจะสมเหตุสมผลหรือไม่ถ้าเป็นคนออกแบบภาษาใหม่ด้วยฟังก์ชั่นที่คล้ายกัน

ตัวอย่างเช่นด้วย C # (และตระกูลอื่น ๆ ของ. NET languages) 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 # จะไม่เริ่มเรียนรู้อะไรอีกหรือ ฉันพบว่ามันยากมากที่จะเชื่อว่านี่เป็นส่วนสำคัญในการตัดสินใจออกแบบของพวกเขา คุณสามารถสำรองคำสั่งของคุณอย่างใด?
stijn

6
ที่น่าสนใจ, Python ทอดทิ้ง (รูปแบบที่เหนือกว่ามาก) %การจัดรูปแบบในความโปรดปรานของสิ่งที่คล้ายกับ .NET ของ{}การจัดรูปแบบเพราะข้อเสนอหลังความยืดหยุ่นมากขึ้น
Konrad Rudolph

3
ทำไมท้องฟ้าจึงเป็นสีฟ้าและทำไมคำว่า "สีฟ้า" จึงมีชื่อว่าสีฟ้า? พวกเขาต้องเลือกอะไรซักอย่าง

คำตอบ:


12

ในฐานะ @Secure notes printfฟังก์ชั่นของ C ได้รับแรงบันดาลใจจากwritefฟังก์ชั่นของ BCPL และถ้าคุณดูที่หน้าวิกิพีเดียสำหรับBCPLมันมีตัวอย่างที่แสดงให้เห็นว่า BCPL writefยังใช้%เพื่อแนะนำตัวระบุรูปแบบ

ดังนั้นเราสามารถอนุมานได้ว่า C ใช้%อย่างใดอย่างหนึ่งเพราะ BCPL ทำหรือด้วยเหตุผลเดียวกับที่ BCPL ทำ ความรู้สึกของฉันคือว่ามันเป็นเพียง%หนึ่งในอักขระ ASCII ที่ใช้กันน้อยที่สุด ... หรืออย่างที่ผู้เขียนคิด เป็นไปได้ว่าพวกเขาไม่ได้ใช้เวลามากมายในการชั่งน้ำหนักทางเลือกต่างๆ ในเวลานั้นทั้ง BCPL และ C เป็นภาษาที่คลุมเครือและผู้เขียนส่วนใหญ่มีสิ่งที่สำคัญกว่าที่จะจัดการกับ

อย่างไรก็ตามมีประแจเล็กน้อยในงาน ในขณะที่ C ได้รับแรงบันดาลใจจาก BCPL มันไม่ชัดเจนเลยว่า C ยืม BCPL I / O ไลบรารีหรือวิธีอื่น ๆ ฉันจำได้ว่าห้องสมุด I / O ของ BCPL ผ่านกระบวนการวิวัฒนาการเกี่ยวกับช่วงเวลาที่ผู้ดำเนินการทำดัชนีมัดข้อมูลเพิ่มเข้าไปในภาษา (อันที่จริงฉันคิดว่าฉันรู้ว่าใครจะรู้เกี่ยวกับเรื่องนั้น)


3
"อันที่จริงฉันคิดว่าฉันรู้ว่าใครจะรู้เกี่ยวกับที่" ... และ? ? ... และ .. อย่าเพียงแค่ปล่อยให้เราด้วยหน้าผาที่แขวน ...
Mawg

2
@Mawg - Brian Knight น่าจะเป็นเช่นนั้น เอียนวิลสันน่าจะ มาร์ตินริชาร์ดส์แน่นอน HTH
สตีเฟ่นซี

6

รายการ Wikipedia ไม่มีข้อมูลเชิงประวัติศาสตร์มากมายไม่เฉพาะเจาะจงprintfแต่เพื่อหลีกเลี่ยงอักขระโดยทั่วไป

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

การอ้างอิงก่อนถึงคำว่า "อักขระหลบหนี" พบได้ในเอกสารทางเทคนิคของ IBM Bob Bemer เห็นได้ชัดว่าเขาเป็นผู้คิดค้นกลไกนี้ในระหว่างที่เขาทำงานกับชุดอักขระ ASCII

ฉันเดาว่า: แบ็กสแลชถูกใช้สำหรับตัวอักษรสตริงแล้วและอักขระอื่นจำเป็นสำหรับสตริงรูปแบบ เป็นไปได้มากว่าพวกเขาจะเลือกตัวละครที่มีความถี่ในการใช้งานปกติและเกิดขึ้นน้อยที่สุด

BTW บทความอื่นที่เกี่ยวข้องเชื่อมโยงกับคำที่ฉันเคยได้ยินมาก่อน:

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

บทความสำหรับprintfมีตัวอย่างข้อมูลเพิ่มเติม แต่ไม่เกี่ยวกับเหตุผล

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

printf variadic ของ C มีต้นกำเนิดในฟังก์ชัน writef ของ BCPL

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.