Tại sao (vị trí <kích thước) như vậy là một mô hình phổ biến trong các điều kiện?


9

Trong một tuyên bố điều kiện (IF) mọi người sử dụng (position < size), nhưng tại sao?
Chỉ quy ước hoặc có một lý do tốt cho điều đó?

Tìm thấy trong tự nhiên:

if (pos < array.length) {
   // do some with array[pos];
}

Hiếm khi tìm thấy:

if (array.length > pos) {
   // do some with array[pos];
}

7
Một trường hợp tôi không ngại có "biến" bên phải là if (MIN <= x && x <= MAX). (Trong một số ngôn ngữ, điều này có thể được viết là MIN <= x <= MAX; trong C, nó hoàn toàn hợp pháp nhưng không có nghĩa là bạn nghĩ nó có nghĩa gì).
Keith Thompson


5
Có thể liên quan đến cách viết [min, max]và không [max, min]. Do đó, việc kiểm tra chỉ là một yếu tố xthuộc về khoảng thời gian bằng cách viết min <= x <= max.
Andres F.

Thật là một conumdrum.
Tulains Córdova

Ví dụ thứ hai có thể được làm rõ thêm như thể (! (Mảng.lengh <= pos)) ...
OldFart

Câu trả lời:


48

Mô hình sâu hơn là chúng ta tự nhiên sử dụng "[điều thay đổi] [so sánh] [điều không thay đổi]" làm thứ tự tiêu chuẩn. Nguyên tắc này đúng với ví dụ của bạn vì vị trí có thể thay đổi, trong khi kích thước thì không.

Ngoại lệ phổ biến duy nhất là khi kiểm tra sự bình đẳng, một số lập trình viên tự rèn luyện cách sử dụng thứ tự ngược lại (được gọi là điều kiện Yoda ) để tránh lỗi chung variable = constantthay vì variable == constantlỗi - Tôi không giữ ý tưởng này vì tôi thấy thứ tự tự nhiên được mô tả ở trên dễ đọc hơn nhiều, chủ yếu là vì đó là cách chúng tôi thể hiện ý tưởng bằng tiếng Anh và bởi vì hầu hết các trình biên dịch hiện đại sẽ phát hiện ra điều này và đưa ra cảnh báo.


3
Tùy thuộc vào các công cụ phát triển của bạn, nhiều người cũng sẽ cảnh báo (hoặc lỗi) về variable = constantcấu trúc.
GalacticCowboy

5
+1. Tìm kiếm "Điều kiện Yoda" để biết thêm chi tiết về constant == variablehiện tượng này.
John M Gant

Gần đây tôi đã thấy điều tương tự trong cơ sở mã của riêng tôi (ví dụ if(DBNull == row["fieldName"]) methodCall()và tự hỏi liệu tôi có bị điên không vì hầu hết thời gian tôi đã thấy nó làm theo cách khác.
Andrew Gray

1
Tôi cũng sẽ thêm rằng (position < size)thường biểu thị một giới hạn trên, do đó, trong thực tế, nó là phần còn lại của lowerbound <= position < upperbound, với kích thước là hướng trên. Với hai ràng buộc rõ ràng, positionchỉ có thể đi ở giữa.
Steve314

4
Nó có lẽ liên quan đến ngôn ngữ; chúng tôi phân tích cú pháp " X điều hành Y " là " X là ( điều hành Y )", giống như mối quan hệ là một đặc điểm của X . Bằng cách hỏi so sánh, chúng tôi đang hỏi liệu X có giá trị tốt hay xấu (và Y được coi là hằng số). Hỏi "pos <Array.length" có cảm giác như hỏi: "Vị trí có ổn không (nhỏ hơn chiều dài mảng)?" Nếu không, có gì đó không ổn về vị trí; cho tôi một vị trí khác, và tôi sẽ rất vui khi làm những gì bạn muốn. Nhưng không có gì sai về chiều dài mảng. Hỏi "mảng.length> pos" có cảm giác như chúng ta nên tăng mảng nếu nó quá ngắn.

14

Lời biện minh duy nhất tôi từng thấy cho nó là nó giống như các dòng số hoặc những thứ tự khác mà chúng ta đã học ở trường. Ví dụ: chúng tôi viết các dòng số như thế này:

<--|--|--|--|--|--|-->
   1  2  3  4  5  6

Những thứ nhỏ hơn xuất hiện bên trái của những thứ lớn hơn. Điều tương tự cũng áp dụng cho những thứ khác như ngày tháng (nghĩ về cách sắp xếp lịch).

Về cơ bản, nó tập trung vào cách chúng ta tự nhiên nghĩ về thứ tự của mọi thứ. Việc đọc mẫu đầu tiên sẽ dễ dàng hơn vì bạn không phải xử lý nhiều về nó.


1
Bạn có nghĩa là biểu thức ước tính giá trị nhỏ hơn đứng đầu trong điều kiện? Làm thế nào bạn có thể chắc chắn điều đó sẽ đúng nếu các giá trị thay đổi thời gian chạy?
Tulains Córdova

@ user61852 Bạn không cần biết giá trị nào khi chạy. Ví dụ: Tôi có 2 giá trị mà tôi tính toán trong thời gian chạy valueA và valueB và tôi muốn kiểm tra giá trị đó nhỏ hơn valueB. Tôi sẽ viết "if (valueA <valueB)". Cho dù valueA kết thúc nhỏ hơn valueB là không quan trọng. Nó dễ dàng hơn (đối với tôi ít nhất) khi nhìn vào điều đó và biết rằng tôi đang tìm kiếm khi valueA nhỏ hơn valueB. Nếu tôi thấy "if (valueB> valueA)" tôi phải dừng lại và suy nghĩ xem cái nào là thứ nhỏ hơn khi tôi đi theo nhánh mã này.
Becuzz

1
Tôi hiều nhầm. Tôi đã bỏ phiếu trả lời xuống. Bây giờ tôi muốn bỏ phiếu, nhưng trang web yêu cầu câu trả lời phải được chỉnh sửa để tôi có thể thay đổi phiếu bầu của mình. Vui lòng thực hiện một số chỉnh sửa để tôi có thể bỏ phiếu.
Tulains Córdova

@ user61852 Bạn có thể thay đổi phiếu bầu của mình ngay bây giờ.
Becuzz

11

Mặc dù chủ yếu là vấn đề quy ước, nhưng theo ý kiến ​​của tôi thì điều này phù hợp nhất với cách chúng ta nghĩ - nó cho thấy mục mà chúng ta nhấn mạnh.

Nếu chúng tôi dịch chúng sang tiếng Anh, đó sẽ là cụm từ "Nếu vị trí nhỏ hơn độ dài mảng", trong đó chủ đề của câu là mục tạm thời.

Để diễn đạt nó theo cách khác, "nếu độ dài mảng lớn hơn vị trí" sẽ đặt độ dài mảng (được coi là giá trị cố định) trong đối tượng và vị trí (thoáng qua) trở thành đối tượng trực tiếp.


3
Trên thực tế (trong câu cuối cùng của bạn) vị trí trở thành đối tượng của giới từ. Nhưng tôi đồng ý với những gì bạn đang cố nói. Trong ngôn ngữ học, chúng tôi sẽ nói rằng vị trí là chủ đề và "nhỏ hơn chiều dài mảng" là nhận xét . "Xu hướng đặt các thành phần cấu thành chủ đề câu-ban đầu (chủ đề chính) là phổ biến." vi.wikipedia.org/wiki/
Kẻ

4

Ý kiến ​​của tôi, và đây chỉ là ý kiến ​​của tôi, đó là một quy ước cho khả năng đọc. Mặc dù hai người giống hệt nhau, họ cảm thấy khác nhau trong não của tôi. Tôi không muốn biết nếu kích thước mảng lớn hơn pos. Tôi muốn biết nếu pos nhỏ hơn kích thước mảng.

Nó giống như một cuộc thảo luận nửa trống so với nửa đầy đủ. Về mặt toán học giống hệt nhau, nhưng bộ não của tôi sẽ thấy chúng khác nhau tùy thuộc vào ngữ cảnh.

Cá nhân, nếu tôi thấy

if (array.lengh > pos) {
    // do some with array[pos];
}

Tôi sẽ bắt đầu suy nghĩ về việc đó có phải là một lỗi hay không và ý nghĩa của lập trình viên. Có phải anh ta đang cố gắng làm một cái gì đó ngoài kiểm tra giới hạn?

Có lẽ tôi chỉ không sáng sủa, nhưng nếu tôi phải thực hiện loại phân tích đó trên mỗi dòng mã, não tôi sẽ bị tổn thương.


3

Để thể hiện những gì một số người đã cố gắng đạt được, theo một cách khác ...

Khi thứ tự không tạo ra sự khác biệt đối với hành vi của chương trình, sự khác biệt rõ ràng là vấn đề dễ đọc nhất đối với con người. Đây là một lý do ngôn ngữ tại sao đặt "chủ đề" bên trái có ý nghĩa:

Trong ngôn ngữ học, chủ đề của một câu là những gì đang được nói đến, và bình luận là những gì đang được nói về chủ đề này. Trong ví dụ này, chúng ta có thể cho rằng đó positionchủ đề và "nhỏ hơn độ dài mảng" là nhận xét . Trong tiếng Anh, và trong nhiều ngôn ngữ khác, chủ đề thường được thể hiện trước khi bình luận.
" Xu hướng đặt các thành phần cấu thành chủ đề câu-ban đầu (chủ đề chính) là phổ biến. "

Vì vậy, một nguyên tắc nhỏ là nghĩ về dòng mã của bạn như một câu (hoặc mệnh đề, trong trường hợp này), quyết định câu đó nói về điều gì , và đặt nó trước nếu bạn có thể. Thông thường, những gì câu "về" sẽ là một biến chứ không phải là một hằng. Nhưng đôi khi bình luận cũng sẽ liên quan đến một biến, vì vậy bạn không thể đi theo đó.


1

Đó là sự kết hợp của hai thứ, cả hai đều đến từ trình biên dịch cơ bản mà các ngôn ngữ ban đầu đã được biên dịch thành (và rất nhiều ngôn ngữ hiện tại).

  1. Mảng là các độ lệch dựa trên zero trong bộ nhớ (tức là đoạn dữ liệu đầu tiên nằm ở đầu khối bộ nhớ được phân bổ ... chỉ số 0). Do đó, việc sử dụng 0..n-1 cho các mảnh khác nhau.

  2. Phân nhánh nếu một giá trị nhỏ hơn một giá trị khác (hoặc đăng ký, v.v.) thường là một lệnh đơn. Do đó việc sử dụng toán tử ít hơn (<) đơn giản.

Vì vậy, mẫu đã chuyển từ trình biên dịch chương trình cũ thành ANSI-C (giống như trình biên dịch macro theo một số cách) và từ đó sang Java và các ngôn ngữ giống C khác.


0

Như nhiều câu trả lời khác đã nói, nó rất dễ đọc hơn:

[thing that varies] [comparison] [thing that does not vary]

Hầu như tất cả mọi người tôi biết sử dụng phong cách này độc quyền.

Có một ngoại lệ, đối với các ngôn ngữ kiểu C sử dụng =để gán và ==so sánh. Nếu bạn vô tình gõ:

if (variable = 5) ...

thay vì:

if (variable == 5) ...

sau đó bạn sẽ không gặp lỗi vì đây là dòng mã hợp lệ. (Một số trình biên dịch và IDE sẽ cảnh báo bạn về việc này, nhưng vẫn rất dễ để có một lỗi đánh máy đơn giản như vậy.)

Tuy nhiên, nếu bạn viết:

if (5 == variable) ...

trình biên dịch / trình thông dịch sẽ báo lỗi vì đó không phải là cấu trúc hợp lệ (dù sao trong hầu hết các ngôn ngữ).

Chuyển đổi này thường được gọi là Điều kiện Yoda .

CẬP NHẬT : Dưới đây là danh sách các địa điểm mà Điều kiện Yoda hữu ích .


-1

Cá nhân, tôi thích điều này:

bool positionIsWithinBounds = pos < array.length;
if (positionIsWithinBounds) {
   // do some with array[pos];
}

... đó là nhiều mã hơn, nhưng cũng rất dễ đọc.


4
+1 để đưa ra so sánh một tên. Thực sự, mặc dù, tôi thích cách tiếp cận này tốt hơn cho các điều kiện phức tạp hơn, và không quá nhiều cho các trường hợp đơn giản như thế này. Nó thực sự làm cho tôi dừng lại để suy nghĩ về "mảng", "giới hạn", "trong", và những gì những bài có ý nghĩa, khi tôi theo bản năng biết ý nghĩa của nó cho posđược > array.length. Nói cách khác, mặc dù nó làm cho ý nghĩa của điều kiện rất rõ ràng, nhưng nó thực sự làm cho việc đọc IMO trở nên khó khăn hơn một chút.
John M Gant

Còn một cái tên khác để theo dõi ...
Ded repeatator

-1

Đó là vấn đề ưu tiên hoặc quy ước. Nếu bạn muốn nhất quán, có hai cách hợp lý như nhau mà bạn có thể thực hiện:

  1. Luôn đặt "chủ đề" lên hàng đầu (nghĩ về nó như một câu) - giá trị mà bài kiểm tra nói về. Vì vậy, ví dụ bạn viếtif (age>5)

  2. Hoặc luôn đặt phần tử nhỏ hơn trước (nghĩ về nó như các giá trị được sắp xếp trên màn hình của bạn theo thứ tự tự nhiên). Vì vậy, ví dụ bạn sẽ viết if (a<b)bất kể mã này chủ yếu là về a hay chủ yếu là về b.

Cả hai quy ước sẽ đề xuất đoạn trích đầu tiên bạn hiển thị thay vì đoạn thứ hai, vì vậy tôi đoán trong trường hợp cụ thể này, bạn có câu trả lời của mình. Tôi nói rằng thật khôn ngoan khi tránh viết mã vi phạm cả (1) và (2) ở đây, vì nó sẽ khiến cho hầu hết mọi người khó đọc hơn.

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.