Sự khác biệt giữa phong cách K & R và One True Brace Style (1TBS) là gì?


48

Tôi đã đọc bài viết Wikipedia về Phong cách thụt lề , nhưng tôi vẫn không hiểu. Sự khác biệt giữa K & R và 1TBS là gì?


Tôi đã đọc ở đâu đó rằng phong cách trong K & R bị chi phối bởi các cân nhắc về không gian - tức là để giảm không gian theo chiều dọc mà mã đã chiếm trong cuốn sách.
ChrisF

@ChrisF nó cũng giảm không gian dọc trên màn hình. Khi chúng tôi có thiết bị đầu cuối dòng 80 col x 25, nó là giá trị nó!
Martin Beckett

7
Apple "goto thất bại" là một ví dụ tuyệt vời của một lỗi nghiêm trọng mà chắc chắn sẽ được ngăn chặn bằng cách sử dụng 1TBS: imperialviolet.org/2014/02/22/applebug.html

4
Lỗi của Apple cũng có thể được ngăn chặn bằng cách đặt câu lệnh trên một dòng duy nhất, hiệu đính, sử dụng trình kiểm tra mã chết hoặc sử dụng ngôn ngữ nhạy cảm thụt lề.
Cees Timmerman

1
@CeesTimmerman, .. hoặc có các bài kiểm tra ...
thoni56

Câu trả lời:


76

Sự khác biệt lớn nhất giữa K & R và One True Brace Style (1TBS) là trong 1TBS, tất cả if, else, while, và forbáo cáo có khai mạc và bế mạc niềng răng, ngay cả khi họ không cần thiết. Mục đích là để dễ dàng chèn các câu lệnh mới và biết chính xác chúng sẽ được nhóm như thế nào.

Ví dụ:

K & R:

int i;
for (i = 0; i < 10; i++)
  printf("Hi.");

1TBS:

int i;
for (i = 0; i < 10; i++) {
  printf("Hi");
}

20

K & R là như thế này:

if (x) 
    a();
else {
    b();
    c();
}

Đó là: niềng răng chỉ được sử dụng khi cần thiết, mở nẹp trên cùng một dòng với câu lệnh kiểm soát, đóng dấu ngoặc trên dòng riêng của nó.

"Một kiểu niềng răng thật" (1TBS hoặc OTBS) biến một câu lệnh được kiểm soát duy nhất thành một câu lệnh ghép bằng cách đặt nó trong dấu ngoặc nhọn:

if (x) {
    a();
} else {
    b();
    c();
}

Kiểu Allman đi xa hơn một chút so với 1TBS và cũng buộc khoảng cách dọc bằng cách đặt nẹp mở trên một đường thẳng:

if (x) 
{
    a();
}
else 
{
    b();
    c();
}

Biên tập:

Tôi vẫn đang cố gắng tìm ra chính xác làm thế nào nó đủ điều kiện là "kiêu ngạo" để nói "Dennis Ritchie là một người cực kỳ thông minh, người không chỉ phát minh ra một ngôn ngữ tốt, mà còn đưa ra một phong cách niềng răng thực sự tốt cho nó."

Đối với những người khăng khăng rằng dù sao nó cũng kiêu ngạo, đây là một thách thức nhỏ: đi đến Sourceforge, Github (v.v.) và chọn ra các dự án sử dụng kiểu giằng K & R. Xem qua hồ sơ về lỗi và cam kết của họ, và cố gắng tìm một lỗi duy nhất gây ra bởi kiểu niềng răng mà họ đã sử dụng.

Nếu bạn không muốn làm nhiều việc như vậy, hãy thử làm một phân tích thống kê đơn giản. So sánh các dự án sử dụng các kiểu nẹp khác nhau và xem liệu bạn có thể hiển thị "bimodality" - sự khác biệt có ý nghĩa thống kê về số lượng lỗi (mức độ nghiêm trọng, v.v.) có tương quan với kiểu giằng không.

Tôi đã làm cả hai điều này một vài năm trước đây và không thể tìm thấy một lỗi nào mà tôi có thể gán cho kiểu giằng, tôi cũng không thể tìm thấy bất cứ điều gì tiếp cận mối tương quan có ý nghĩa thống kê giữa hai điều này. Tính trung bình, những người sử dụng K & R giằng có lỗi ít hơn một chút, nhưng sự khác biệt là nhiều quá nhỏ để đủ điều kiện như ý nghĩa thống kê.

Vì nó đã được đưa lên, tôi sẽ bình luận về tình huống với các macro đa câu lệnh. Một macro bao gồm nhiều câu lệnh nhưng không bao quanh chúng bằng chính dấu ngoặc nhọn, có một lỗi. Công việc của tôi không phải là viết mã che đi lỗi đó. Hoàn toàn ngược lại, công việc của tôi là tìm và loại bỏ lỗi đó càng nhanh càng tốt.

Viết mã với hy vọng nó che đậy các lỗi để chúng không bị phát hiện và không được sửa chữa là hết sức xấu xa. Gọi đó là kiêu ngạo nếu bạn thích, nhưng tôi không thấy điều này thậm chí gần với thương lượng. Lỗi nên được tìm thấy và cố định, không được che đậy. Càng tồn tại lâu, càng có nhiều khả năng chúng sẽ trở nên khó khăn hơn và tốn kém hơn để sửa chữa.


1
Xóa tất cả các ý kiến ​​khi họ đã đi xuống để cãi nhau và tiếng ồn. Nếu bạn có một điểm hợp lệ thì hãy đăng nó như một câu trả lời. Nếu bạn muốn một cuộc thảo luận, hãy tham gia trò chuyện
ChrisF

8
không phải 1tbs đặt} và các dòng khác trên một dòng sao? Tiết kiệm không gian theo chiều dọc trong khi vẫn giữ được sự đối xứng tuyệt đẹp là điểm chính!
Martin Beckett

4
@Jerry - tốt, bất kỳ cuộc chiến thánh thiện nào cũng cần một vài sơ đồ ;-)
Martin Beckett

6
goto thất bại; goto thất bại;
Jamie Pate

9
Có để theo dõi bình luận của @ JamiePate, đó là lỗi Apple SSL được phân tích ở đây . Có một iftuyên bố với các câu lệnh thụt vào sau nó, do đó có vẻ như cả hai đều được thực hiện có điều kiện. Nhưng không có niềng răng! Câu lệnh thứ hai thực sự vượt quá ifvà sẽ luôn luôn được thực thi, do đó là lỗi.
Colin D Bennett

9

Vấn đề, nói chung với phong cách cú đúp KR là trong tái cấu trúc mã. Khi di chuyển mã xung quanh rất dễ bỏ lỡ rằng không có dấu ngoặc xung quanh thứ gì đó, di chuyển nó không chính xác (hoặc di chuyển một cái gì đó theo nó nghĩ rằng nó được thực thi một cách có điều kiện) và sau đó gãi đầu khi một cái gì đó không còn hoạt động, hoặc không may và ở trong một vùng mã không được kiểm tra tốt và lỗi không được chú ý cho đến khi một chiếc mũ đen tìm được cách khai thác nó. Một chuyến đi nhanh vào trình gỡ lỗi dễ dàng tìm thấy sự cố nếu bạn nhận thấy nó, nhưng nếu bạn không ...


2
điều này dường như chỉ lặp lại điểm được thực hiện và giải thích trong các câu trả lời trước
gnat

1
Tôi không nghĩ các câu trả lời khác giải thích chính xác vấn đề phát sinh trong mã hàng ngày. Họ giải thích OTB là gì, nhưng không hiểu tại sao nó thực sự quan trọng. Nhận xét có thể giải quyết điều đó, nhưng không phải là câu trả lời.
Justin Swanhart
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.