Tại sao dấu phần trăm (%) được chọn làm công cụ xác định định dạng cho họ hàm printf?


27

Mọi người đều biết rằng, ít nhất là trong C, bạn sử dụng printfhọ các hàm để in một chuỗi được định dạng. Và các hàm này sử dụng dấu phần trăm ( %) để biểu thị sự bắt đầu của một công cụ xác định định dạng. Ví dụ: %dcó nghĩa là in một int%ucó nghĩa là in một unsigned int. Nếu bạn không quen với cách thức giữ printfchức năng và định dạng hoạt động, hoặc đơn giản chỉ cần làm mới, bài viết Wikipedia là một nơi tốt để bắt đầu.

Câu hỏi của tôi là, có một lý do đặc biệt thuyết phục tại sao điều này ban đầu hoặc nên được chọn trong tương lai làm công cụ xác định định dạng?

Rõ ràng là quyết định đã được đưa ra từ lâu (rất có thể là tiền thân của ngôn ngữ C) và nó ít nhiều đã trở thành "tiêu chuẩn" kể từ đó (không chỉ ở C, mà còn trong một loạt các ngôn ngữ khác mà đã áp dụng cú pháp của nó ở các mức độ khác nhau), vì vậy đã quá muộn để thay đổi. Nhưng tôi vẫn tò mò liệu có ai có cái nhìn sâu sắc về lý do tại sao sự lựa chọn này có thể được đưa ra ngay từ đầu không, và liệu nó có còn ý nghĩa như sự lựa chọn hay không nếu một người đang thiết kế một ngôn ngữ mới có chức năng tương tự.

Ví dụ, với C # (và họ ngôn ngữ .NET khác), Microsoft đã đưa ra một quyết định hơi khác về hoạt động của các chức năng định dạng chuỗi. Mặc dù một số mức độ an toàn loại có thể được thi hành ở đó (không giống như việc thực hiện printftrong C), và do đó không cần thiết phải bao gồm một dấu hiệu của loại tham số tương ứng, họ đã quyết định sử dụng các cặp dấu ngoặc nhọn có chỉ số bằng không ( {}) như định dạng định dạng, như vậy:

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.

Tài liệu cho String.Formatphương pháp này chứa nhiều thông tin hơn, cũng như bài viết này về định dạng tổng hợp nói chung , nhưng các chi tiết chính xác là không quan trọng. Vấn đề đơn giản là họ đã từ bỏ thói quen sử dụng lâu đời %để chỉ ra sự khởi đầu của một công cụ xác định định dạng. Ngôn ngữ C có thể dễ dàng sử dụng {d}{u}, nhưng không. Bất cứ ai cũng có bất kỳ suy nghĩ về lý do tại sao, liệu quyết định này có ý nghĩa khi nhìn lại, và liệu các triển khai mới nên theo nó?

Rõ ràng là không có nhân vật nào có thể được chọn mà sẽ không thể thoát được để có thể đưa nó vào chuỗi, nhưng vấn đề đó đã được giải quyết khá tốt chỉ bằng cách sử dụng hai trong số chúng. Những cân nhắc khác có liên quan?


5
Vấn đề thoát không được giải quyết bằng cách sử dụng hai ký tự. Nó chỉ có nghĩa là bạn có thêm một nhân vật để trốn thoát.
JJJ

2
Tôi tò mò. Chắc chắn, nó sẽ có thể sử dụng {u}thay thế %unhưng nó sẽ có lợi thế đáng kể nào? Có vẻ như một sự lựa chọn phần lớn tùy ý.
CB Bailey

12
@JarrodRoberson vì vậy bạn đang nói rằng họ cố tình chọn {}cú pháp để mọi người học C # sẽ không bắt đầu học bất cứ điều gì khác? Tôi thấy rất khó tin rằng đó là một phần chính, thậm chí là một phần trong quyết định thiết kế của họ. Bạn có thể sao lưu tuyên bố của bạn bằng cách nào đó?
stijn

6
Thật thú vị, Python đã từ bỏ %định dạng (một hình thức vượt trội hơn nhiều) để ủng hộ một cái gì đó giống với {}định dạng của .NET vì cái sau cung cấp sự linh hoạt hơn.
Konrad Rudolph

3
Tại sao bầu trời màu xanh và tại sao từ "màu xanh" được đặt tên là màu xanh? Họ phải chọn một cái gì đó.

Câu trả lời:


12

Như @Secure lưu ý, printfchức năng của C được lấy cảm hứng từ writefchức năng của BCPL . Và nếu bạn xem trang wikipedia cho BCPL , nó có một ví dụ cho thấy BCPL writefcũng được sử dụng %để giới thiệu một công cụ xác định định dạng.

Vì vậy, chúng ta có thể suy ra rằng C đã sử dụng %vì BCPL đã làm hoặc vì những lý do tương tự mà BCPL đã làm. Cảm giác ruột của tôi là nó đơn giản %là một trong những ký tự ASCII ít được sử dụng nhất ... hoặc các tác giả nghĩ vậy. Cũng có khả năng là họ đã không dành nhiều thời gian để cân nhắc các phương án khác nhau. Vào thời điểm đó, cả BCPL và C đều là những ngôn ngữ tối nghĩa và các tác giả rất có thể có những điều quan trọng hơn để giải quyết.

Tuy nhiên, có một cờ lê nhỏ trong công trình. Mặc dù C được truyền cảm hứng từ BCPL, nhưng không hoàn toàn rõ ràng liệu C đã mượn các thư viện I / O BCPL hay ngược lại. Tôi lờ mờ nhớ rằng các thư viện I / O của BCPL đã trải qua một quá trình tiến hóa về thời gian mà toán tử lập chỉ mục byte kết hợp được thêm vào ngôn ngữ. (Trên thực tế, tôi nghĩ rằng tôi biết ai sẽ biết về điều đó.)


3
"Thật ra, tôi nghĩ tôi biết ai sẽ biết về điều đó" ... và? ... và? .. Đừng để chúng tôi với một cái móc treo ...
Mawg

2
@Mawg - Brian Knight có lẽ sẽ. Ian Wilson có thể sẽ. Martin Richards chắc chắn sẽ. HTH.
Stephen C

6

Mục nhập Wikipedia không chứa nhiều thông tin lịch sử, không cụ thể printf, nhưng để thoát các ký tự nói chung.

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

Tham khảo sớm về thuật ngữ "nhân vật thoát hiểm" được tìm thấy trong các ấn phẩm kỹ thuật IBM của Bob Bemer's. Rõ ràng, chính ông là người đã phát minh ra cơ chế này, trong quá trình làm việc với bộ ký tự ASCII.

Tôi đoán là: Dấu gạch chéo ngược đã được sử dụng cho chuỗi ký tự và một ký tự khác là cần thiết cho chuỗi định dạng. Nhiều khả năng họ đã chọn nhân vật có tần suất sử dụng và xuất hiện bình thường ít nhất.

BTW, một bài viết liên quan khác được liên kết ở đó với một thuật ngữ mà tôi đã nghe trước đây:

http://en.wikipedia.org/wiki/Leaning_toothpick_sy Triệu chứng

Bài viết cho printfcó một số đoạn thông tin thêm, nhưng không phải về lý do.

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

Printfic của C có nguồn gốc từ chức năng writef của BCPL.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.