Tại sao các mảng dựa trên zero là chuẩn?


112

Một câu hỏi được hỏi ở đây làm tôi nhớ đến một cuộc thảo luận tôi đã có với một lập trình viên đồng nghiệp. Ông lập luận rằng các mảng dựa trên zero nên được thay thế bằng các mảng dựa trên một vì các mảng dựa trên zero là một chi tiết triển khai bắt nguồn từ cách các mảng và con trỏ và phần cứng máy tính hoạt động, nhưng những thứ này không nên được phản ánh ở mức cao hơn ngôn ngữ.

Bây giờ tôi không thực sự giỏi trong việc tranh luận vì vậy tôi thực sự không thể đưa ra bất kỳ lý do chính đáng nào để gắn bó với các mảng dựa trên số 0 ngoài việc họ cảm thấy thích hợp hơn. Tại sao zero điểm xuất phát chung cho mảng?


Trong một mảng phần tử n, phần tử 'n' không xuất hiện. Một mảng phần tử n có các thành viên chỉ có số từ 0 đến n-1. Vì vậy, sẽ không tốt hơn nếu chúng ta có một mảng bắt đầu từ 1 và vì vậy một mảng phần tử n thực sự đại diện cho n phần tử có trong mảng.

Tôi thích các mảng dựa trên zero vì bit đầu tiên trong một byte là 2 ^ 0, không phải 2 ^ 1. Điều này đôi khi giúp tôi :)
e-MEE

Nếu một người nhìn vào danh sách này chẳng hạn, en.wikipedia.org/wiki/ , người ta sẽ nhận thấy rằng hầu hết các ngôn ngữ cụ thể trong miền bắt đầu lập chỉ mục ở mức 1 và hầu hết các ngôn ngữ từ trường cs suy nghĩ ở mức 0. Nếu một người tìm kiếm lâu hơn một chút , anh ta sẽ nhận thấy rằng rất nhiều cuộc thảo luận ngu ngốc đã được thực hiện về chủ đề này, rằng có lẽ thật vô nghĩa khi cố gắng nói bất kỳ ai trong hai người để thay đổi cách của họ. Để bảo vệ "1", hầu hết mọi người trên thế giới đều sử dụng cái đó. Hầu hết các lập trình viên sử dụng "0". Hầu hết mọi người không hiểu lập trình viên, vì vậy điều đó khiến bạn phải suy nghĩ ...
Rook

Tôi không thể tin rằng câu hỏi này đã được chuyển từ StackOverflow sang Lập trình viên, và sau đó, đóng lại là không mang tính xây dựng. Thật là ngu ngốc.
paercebal

Câu trả lời:


105

Tôi không nghĩ bất kỳ ai trong chúng ta có thể đưa ra một lập luận mạnh mẽ hơn bài viết của Edsger W. Dijkstra "Tại sao việc đánh số nên bắt đầu từ 0" .


Ông đã đưa ra một số số liệu thống kê và sử dụng bằng chứng phong cách toán học. Nhưng tôi chắc rằng ai đó vẫn có thể tranh luận. Mặc dù tôi chấp thuận nên tôi sẽ không.

6
Bài viết của Dijkstra là về phong cách, nhưng sau đó, lập luận của ông là về sự đơn giản và dễ sử dụng ... +1.
paercebal

80

Đối số thẩm quyền

Chà ... Rõ ràng, hầu hết các ngôn ngữ, kể cả những ngôn ngữ gần đây, đều dựa trên không. Vì những ngôn ngữ đó được viết bởi những người khá thành thạo, bạn của bạn phải sai ...

Tại sao một?

Tại sao 1 sẽ là một chỉ số bắt đầu tốt hơn 0? Tại sao không phải 2, hay 10? Câu trả lời tự nó rất thú vị vì nó cho thấy rất nhiều về quá trình mặc dù mọi người bảo vệ ý tưởng.

Các đầu tranh luận là nó tự nhiên hơn, bởi vì 1 thường là một trước khi tất cả những người khác, ít nhất, đối với đa số người ...

Đối số số một là chỉ mục cuối cùng cũng là kích thước của mảng ...

Tôi vẫn bị ấn tượng bởi "chất lượng" của những lý do tôi thường nghe cho loại tranh luận này ... Và thậm chí nhiều hơn khi tôi nhắc rằng ...

Tại sao không bằng không?

... Các ký hiệu "một nền tảng" còn sót lại từ văn hóa phương Tây mà bỏ qua sự tồn tại của số 0 trong nhiều thế kỷ, nếu không muốn nói là nhiều hơn.

Dù bạn có tin hay không, lịch gốc của gregorian đi từ -3, -2, -1, 1, 2, 3 ... Hãy thử tưởng tượng vấn đề mà nó đã đóng góp cho khoa học phương tây (ví dụ, bao nhiêu năm kể từ ngày 1 tháng 1 -2 đến ngày 1 tháng 1 để xem hơn lịch gốc của gregorian xung đột với một cái gì đó đơn giản như chất nền ...).

Giữ một dựa trên mảng là như thế nào (tốt, tôi sẽ được downmodded cho rằng ... ^ _ ^ ...), giữ để dặm bãi trong thế kỷ 21 ...

Tại sao không? Bởi vì đó là toán học!

Đầu tiên (OOops ... Xin lỗi ... Tôi sẽ thử lại)

Zero , Zero không là gì cả, một là một cái gì đó. Và một số văn bản tôn giáo cho rằng "Lúc đầu, không có gì". Một số cuộc thảo luận liên quan đến máy tính có thể bùng cháy như các cuộc tranh luận tôn giáo, vì vậy điểm này không nằm ngoài chủ đề vì có vẻ như ... ^ _ ^

Đầu tiên , làm việc với mảng dựa trên zero dễ dàng hơn và bỏ qua giá trị 0 của nó so với làm việc với mảng dựa trên một lần và hack xung quanh để tìm giá trị 0 của nó. Lý do này gần như ngu ngốc như trước đây, nhưng sau đó, đối số ban đầu ủng hộ các mảng dựa trên một cũng khá ngụy biện.

Thứ hai , chúng ta hãy nhớ rằng khi xử lý các con số, rất có thể bạn sẽ đối phó với toán học lúc này hay lúc khác, và khi bạn đối phó với toán học, rất có thể bạn sẽ không có tâm trạng cho những vụ hack ngu ngốc để vượt qua những quy ước lỗi thời. Các ký hiệu dựa trên một nền tảng đã làm vấy bẩn toán học và ngày tháng trong nhiều thế kỷ, và bằng cách học hỏi từ những sai lầm của chúng ta, chúng ta nên cố gắng tránh nó trong các ngành khoa học định hướng trong tương lai (bao gồm cả ngôn ngữ máy tính).

Thứ ba , đối với các mảng ngôn ngữ máy tính được gắn với phần cứng, hãy phân bổ một mảng C gồm 21 số nguyên và di chuyển con trỏ 10 chỉ số sang phải và bạn sẽ có một mảng [-10 đến 10] tự nhiên. Điều này không tự nhiên đối với phần cứng. Nhưng nó là dành cho toán học. Tất nhiên, toán học có thể bị lỗi thời, nhưng lần cuối cùng tôi kiểm tra, hầu hết mọi người trên thế giới đều tin rằng nó không phải vậy.

Bốn , Như đã chỉ ra ở nơi khác, ngay cả đối với vị trí rời rạc (hoặc khoảng cách giảm xuống các giá trị rời rạc), chỉ số đầu tiên sẽ bằng 0, giống như sàn trong tòa nhà (bắt đầu từ 0), đếm ngược giảm (3, 2, 1, ZERO !), độ cao mặt đất, pixel đầu tiên của hình ảnh, nhiệt độ (zero Kelvin, đối với độ không tuyệt đối hoặc 0 độ C, khi nhiệt độ đóng băng của nước là 273 K). Trong thực tế, điều duy nhất thực sự bắt đầu với một là cách truyền thống " thứ nhất , thứ hai , thứ ba , v.v." ký hiệu lặp lại , dẫn tôi tự nhiên đến điểm tiếp theo ...

Năm sự tiếp điểm (trong đó một cách tự nhiên theo trước ) là container cấp cao nên được truy cập, không theo chỉ số, nhưng bằng cách lặp , trừ khi các chỉ số chính mình có một giá trị nội tại. Tôi ngạc nhiên khi người ủng hộ "ngôn ngữ cấp cao hơn" của bạn không đề cập đến điều đó. Trong trường hợp bản thân chỉ số là quan trọng, bạn có thể đặt cược một nửa thời gian bạn có một câu hỏi liên quan đến toán học trong đầu. Và do đó, bạn muốn hộp đựng của mình thân thiện với toán học và không bị vô hiệu hóa toán học như "lịch cũ của bạn" bắt đầu từ 1, và cần các bản hack được lấy lại để làm cho nó hoạt động.

Phần kết luận

Đối số được đưa ra bởi lập trình viên đồng nghiệp của bạn là ngụy biện bởi vì nó không cần thiết ràng buộc các thói quen ngôn ngữ nói / viết, về bản chất, mờ, với ngôn ngữ máy tính (nơi bạn không muốn hướng dẫn của mình bị mờ) và bởi vì gán sai phần cứng Lý do cho vấn đề này, he.she hy vọng sẽ thuyết phục bạn, khi các ngôn ngữ ngày càng trừu tượng hơn, rằng mảng dựa trên zero là một điều của quá khứ.

Mảng dựa trên zero là dựa trên zero vì lý do liên quan đến toán học. Không vì lý do liên quan đến phần cứng.

Bây giờ, nếu đây là một vấn đề đối với lập trình viên đồng nghiệp của bạn, hãy để anh ta bắt đầu lập trình với các cấu trúc cấp cao thực sự, như các vòng lặp và các vòng lặp foreach.


độ không bằng 0 là 273,15K;)

2
Tôi biết (tôi có bằng Thạc sĩ Vật lý), nhưng tôi cảm thấy chơi với số thập phân ít hơn so với khía cạnh hài hước mà tôi đã cố gắng tô màu cho các cuộc tranh luận của mình với ... ^ _ ^ ...
paercebal

20
Đoạn văn của bạn được gắn nhãn "Không, Thứ nhất, Thứ hai, Thứ ba, Bốn, Năm". Để thống nhất, bạn nên sử dụng các số chính ("Không, Một, Hai, Ba, Bốn, Năm") hoặc số thứ tự ("Zeroth, Thứ nhất, Thứ hai, Thứ ba, Thứ tư, Thứ năm"). :-)
ShreevatsaR

10
Tương tự như vậy, trong năm đầu tiên của cuộc đời, chúng ta không phải một tuổi mà là 0 tuổi

3
@Nikita Rybak: Điều đáng kinh ngạc là bạn đã bỏ lỡ những gì được xem bởi tất cả các nhà bình luận trước bạn: Tất nhiên câu trả lời của Bill the Lizard là đúng. Đây là lý do tại sao tôi bình chọn cho anh ấy +1 và đây là lý do tại sao nó được chọn là câu trả lời hay nhất cho câu hỏi. Câu trả lời của tôi là nhiều hơn về việc tạo niềm vui cho những lý do ngụy biện đằng sau mảng dựa trên 1 và đưa ra các trường hợp cụ thể trong đó mảng dựa trên 1 sẽ gây phiền toái. Tuy nhiên, tôi ngạc nhiên khi bạn thấy "không phải là một người thuyết phục duy nhất", thậm chí xem xét các lý do được trộn lẫn với sự mỉa mai ...
paercebal

47

Khoảng thời gian nửa mở sáng tác tốt. Nếu bạn đang giao dịch 0 <= i < limvà bạn muốn mở rộng theo ncác yếu tố, các yếu tố mới có chỉ số trong phạm vi lim <= i < lim + n. Làm việc với các mảng dựa trên zero giúp số học dễ dàng hơn khi chia hoặc ghép các mảng hoặc khi đếm các phần tử . Người ta hy vọng số học đơn giản hơn dẫn đến ít lỗi hàng rào hơn .


+1 cho các khoảng thời gian nửa mở - nó chỉ làm cho mọi thứ dễ dàng hơn.
Nhật thực

29

Một số loại thao tác mảng nhất định trở nên phức tạp với các mảng dựa trên 1, nhưng vẫn đơn giản hơn với các mảng dựa trên 0.

Tôi đã làm một số chương trình phân tích số tại một điểm. Tôi đã làm việc với các thuật toán để thao tác các ma trận nén, thưa thớt, được viết bằng cả FORTRAN và C ++.

Các thuật toán FORTRAN có rất nhiều a[i + j + k - 2], trong khi C ++ có a[i + j + k], vì mảng FORTRAN dựa trên 1, trong khi mảng C ++ là dựa trên 0.


Tôi đồng ý. Khoảnh khắc duy nhất mà tôi thấy mảng dựa trên 1 hữu ích là khi tôi muốn tạo khoảng trống cho chỉ mục null. Chẳng hạn, nếu tôi có một mảng các đối tượng và sử dụng các chỉ mục của chúng làm tay cầm và muốn có một tay cầm null.
Fabio Ceconello

Tôi cũng đã gặp phải sự phức tạp không cần thiết của 1 mảng dựa trên, 0 mảng dựa trên kinh nghiệm hạn chế của tôi, luôn tạo ra mã rõ ràng hơn để lập chỉ mục mảng với ngoại lệ hiếm.

Các chỉ số FORTRAN và C ++ sẽ khác nhau như thế nào nếu các chỉ số tương ứng của chúng chỉ được bù bằng 1? Ngoài ra, tại sao trừ 2? Nếu FORTRAN dựa trên 1, thì bạn sẽ không thêm 2 (hoặc 1)?
RexE

@RexE: Đó là cách nó hoạt động và đó là lý do tại sao nó quá phức tạp với các mảng dựa trên 1.
Jay Bazuzi

@RexE: Giả sử bạn mô phỏng một mảng 3d với một mảng phẳng. Sau đó, trong 0 cơ sở, phần tử (0 0 0) tương ứng với phần tử 0 trong mảng phẳng. OTOH, nếu nó dựa trên 1, phần tử (1 1 1) tương ứng với phần tử 1 trong mảng phẳng: 1 + 1 + 1-2.

22

Chỉ mục trong một mảng không thực sự là một chỉ mục. Nó chỉ đơn giản là một phần bù là khoảng cách từ điểm bắt đầu của mảng. Phần tử đầu tiên là ở đầu mảng nên không có khoảng cách. Do đó phần bù là 0.


3
Đối với hầu hết các ngôn ngữ được thiết kế hiện nay, đây thực sự là một chi tiết triển khai, không nên xuất hiện trong ngôn ngữ (ngoại trừ khi có những lý do khác tốt hơn để làm như vậy)
Jens Schauder

17

Những lý do không chỉ là lịch sử: C và C ++ vẫn còn tồn tại và được sử dụng rộng rãi và số học con trỏ là một lý do rất hợp lệ để có các mảng bắt đầu ở chỉ số 0.

Đối với các ngôn ngữ khác thiếu số học con trỏ, cho dù phần tử đầu tiên nằm ở chỉ số 0 hoặc 1 là một quy ước hơn là bất cứ điều gì khác.
Vấn đề là các ngôn ngữ sử dụng chỉ số 1 làm thành phần đầu tiên của chúng không tồn tại trong chân không và thường phải tương tác với các thư viện thường được viết bằng - bạn đoán nó - C hoặc C ++ ...

VB và các hương vị có nguồn gốc của nó đã phải chịu đựng khi các mảng bắt đầu từ 0 hoặc 1 và đó là một vấn đề trong một thời gian dài.

Điểm mấu chốt là: không quan trọng ngôn ngữ của bạn xem xét chỉ số phần tử đầu tiên miễn là nó phù hợp xuyên suốt. Vấn đề là việc coi 1 là chỉ số đầu tiên làm cho nó khó hơn khi làm việc với thực tế.


Đã đồng ý. Vấn đề nhất quán và trừ khi bạn có sự xa xỉ trong việc tránh mã cấp thấp (bao gồm cả C / C ++) hoàn toàn sau đó làm việc với các mảng dựa trên 1 chỉ là vấn đề rắc rối.
Shog9

Trong khi chúng ta đang ở đó, một câu hỏi: bạn có bao giờ sử dụng mã cấp thấp theo cách không cụ thể không? Nói cách khác, bạn luôn ở trên nền tảng này hay nền tảng khác và bạn phải biết cái nào, phải không?
Dan Rosenstark

1
Là một người nghĩ rằng VB .NET thường không công bằng, tôi phải nói rằng thực tế VB .NET trên mảng là khủng khiếp. Họ phân chia sự khác biệt và làm cho nó trở nên khó hiểu hơn: Mảng bắt đầu từ 0, nhưng Dim a as Integer (5) tạo ra một mảng với 6 vị trí. Lý do dường như là có thêm một vị trí tốt hơn là có lỗi trong việc giải quyết quá độ dài của mảng. Thật không may về điều đó (và các vấn đề khác, như And và Hoặc là bitwise), họ đã gặp phải yêu cầu từ rất nhiều lập trình viên VB6, những người cuối cùng đã không sử dụng VB .NET.
Kyralessa

1
@Kyralessa: Không, lý do là có khả năng tương thích ngược với VB6 (trợ lý nâng cấp tự động) mặc dù họ nhận thức rõ rằng ký hiệu này là phản trực giác và dễ bị lỗi. Mặt khác, AndOrbitwise không liên quan gì đến VB6, đó là giải pháp hợp lý duy nhất cho ngôn ngữ kiểu VB. Bạn làmAndAlsoOrElsecho các hoạt động logic của bạn.
Konrad Rudolph

AndOrbitwise có mọi thứ để làm với VB6, bởi vì chúng là bitwise trong VB6. Các toán tử xấu AndAlsoOrElsenên được thực hiện theo chiều bit, vì các phép toán bitwise ít phổ biến hơn nhiều so với các toán tử logic. Có rất nhiều mụn cóc xấu xí như thế còn sót lại trên ngôn ngữ do "khả năng tương thích ngược", giống như thực tế là ByVal được dán khắp nơi mặc dù đó là mặc định.
Kyralessa

10

Mảng dựa trên zero có nguồn gốc từ C và thậm chí là trình biên dịch chương trình. Với C, con trỏ toán học về cơ bản hoạt động như thế này:

  • Mỗi phần tử của một mảng chiếm một số byte nhất định. Một số nguyên 32 bit là (rõ ràng) 4 byte;
  • Địa chỉ của một mảng được chiếm bởi phần tử đầu tiên của mảng với các phần tử tiếp theo trong các khối liền kề có kích thước bằng nhau sau đó.

Để minh họa, giả sử int a[4]là 0xFF00, các địa chỉ là:

  • một [0] -> 0xFF00;
  • một [1] -> 0xFF04;
  • một [2] -> 0xFF08;
  • a [3] -> 0xFF0C.

Vì vậy, với các chỉ số dựa trên zero, toán học addres rất đơn giản:

Địa chỉ của phần tử = Địa chỉ của mảng + chỉ mục * sizeof (loại)

Trong thực tế, các biểu thức trong C đều tương đương:

  • một [2];
  • 2 [a]; và
  • * (a + 2).

Với các mảng dựa trên một, toán học phức tạp hơn bao giờ hết.

Vì vậy, lý do phần lớn là lịch sử.


1
Câu hỏi ban đầu đã nêu rõ "các mảng bằng 0 là một chi tiết triển khai bắt nguồn từ cách các mảng và con trỏ và phần cứng máy tính hoạt động, nhưng những thứ này không nên được phản ánh trong các ngôn ngữ cấp cao hơn."

Đáng nói là các ngôn ngữ cho phép mảng dựa trên N thường tạo mã với mảng 'offset' được tính toán tự động với chi phí thời gian chạy bằng không.
Roddy

8

Nếu bạn sử dụng mảng dựa trên zero, độ dài của mảng là tập hợp các chỉ số hợp lệ. Ít nhất, đó là những gì số học Peano nói:

0 = {}
1 = 0 U {0} = {0}
2 = 1 U {1} = {0,1}
3 = 2 U {2} = {0,1,2}
...
n = n-1 U {n-1} = {0,1,2...n-1}

Vì vậy, đó là ký hiệu tự nhiên nhất, theo một nghĩa nào đó.


7

Bởi vì có mối tương quan chặt chẽ giữa mảng và con trỏ trong C

char* p = "hello";
char q[] = "hello";

assert(p[1] == q[1]);

assert(*p == *q)

* p giống như * (p + 0)

có chỉ số bắt đầu là 1 sẽ khiến bạn đau đầu sau này


5

Một đống là một ví dụ về những lợi thế của mảng dựa trên 1. Đưa ra một chỉ số i , chỉ số của tôi 's cha mẹ và con bên trái là

PARENT[ i ] = i ÷ 2

LCHILD[ i ] = i × 2

Nhưng chỉ cho các mảng dựa trên 1. Đối với mảng dựa trên 0, bạn có

PARENT[ i ] = ( i + 1) ÷ 2 - 1

LCHILD[ i ] = ( i + 1) × 2 - 1

Và sau đó bạn có thuộc tính mà tôi cũng là kích thước của mảng con cho chỉ mục đó (tức là các chỉ số trong phạm vi [1, i ]).

Nhưng cuối cùng, điều đó không thành vấn đề, bởi vì bạn có thể biến mảng dựa trên 0 thành mảng dựa trên 1 bằng cách phân bổ thêm một phần tử so với bình thường và bỏ qua zeroth. Do đó, bạn có thể chọn tham gia để nhận được lợi ích của mảng dựa trên 1 khi thích hợp và giữ các mảng dựa trên 0 để số học sạch hơn trong hầu hết các tình huống khác.


4

Cảm giác của tôi là nó hoàn toàn tùy ý. Không có gì đặc biệt về mảng không hoặc một dựa trên. Kể từ khi giải phóng bản thân khỏi Visual Basic (chủ yếu, đôi khi tôi làm những việc nhỏ nhặt trong Excel), tôi đã không làm việc với các mảng dựa trên 1 và ... nó cũng vậy. Thực tế là nếu bạn cần phần tử thứ ba của mảng, thì đó chỉ là chi tiết triển khai được gọi là 3 hoặc 2. Tuy nhiên, 99% công việc bạn làm với mảng chỉ quan tâm đến hai điểm tuyệt đối: phần tử đầu tiên và số lượng hoặc chiều dài. Một lần nữa, đó chỉ là một chi tiết triển khai rằng phần tử đầu tiên được gọi là 0 thay vì một hoặc phần tử cuối cùng được gọi là đếm-1 hoặc, thay vào đó, đếm.

Chỉnh sửa: Một số người trả lời đã đề cập rằng các mảng dựa trên 1 dễ bị lỗi hàng rào hơn. Theo kinh nghiệm của tôi, nghĩ về nó bây giờ, điều này là đúng. Tôi nhớ mình đã nghĩ, trong VB, "cái này sẽ hoạt động hoặc sẽ nổ tung vì tôi tắt một cái." Trong Java điều đó không bao giờ xảy ra. Mặc dù tôi nghĩ rằng tôi đã khá hơn, nhưng một số người trả lời chỉ ra các trường hợp trong đó mảng dựa trên 0 dẫn đến số học đẹp hơn, NGAY CẢ khi bạn không phải đối phó với lang cấp thấp hơn.


Trong PHP, hầu hết các tìm kiếm bên trong hàm chuỗi trả về FALSE không tìm thấy. Không -1.
jmucchiello

Bạn đang nhầm lẫn số đếm với chỉ số của phần tử cuối cùng. Số lượng của một mảng trống luôn là 0, cho dù bạn sử dụng mảng dựa trên không hay dựa trên một. Ưu điểm của mảng dựa trên một là số đếm là vị trí của phần tử cuối cùng (nhưng đó là về lợi thế duy nhất).

Đúng về cả hai điểm này: đã xóa một nửa cuối cùng, vì nó giống nhau cho các mảng dựa trên 0 hoặc một dựa trên: đếm là 0 nếu bạn có các phần tử bằng không.
Dan Rosenstark

Ý tôi là nửa cuối câu trả lời của tôi ...
Dan Rosenstark

4

Là một lập trình viên C / C ++ hơn 10 năm, với nền tảng rất mạnh về Pascal và Delphi, tôi vẫn bỏ lỡ việc kiểm tra loại chỉ mục và ràng buộc mảng mạnh của Pascal, và tính linh hoạt và an toàn đi kèm với nó. Một ví dụ rõ ràng về điều này là một dữ liệu mảng giữ các giá trị cho mỗi tháng.

Pascal:

 Type Month = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);

  Var Days[Month] of integer;

  ... 
  if Year mod 4 = 0 then // yes this is vastly simplified for leap years and yes i don't know what the comment marker is in pascal and no i won't go look it up
    Days[Feb] := 29
  else
    Days[Feb] := 28;

Viết mã tương tự bằng các ngôn ngữ C mà không sử dụng +/- 1 hoặc 'số ma thuật' là một thách thức khá lớn. Lưu ý rằng các biểu thức như Ngày [2] và Ngày [Tháng 1 + Tháng 12] đơn giản sẽ không được biên dịch, điều này có thể xuất hiện tàn bạo đối với những người vẫn nghĩ trong C hoặc Trình biên dịch.

Tôi phải nói rằng có nhiều khía cạnh của các ngôn ngữ Pascal / Delphi mà tôi không bỏ lỡ một chút nào, nhưng các mảng dựa trên C zero dường như chỉ "câm" khi so sánh.


Có thể đáng lưu ý rằng thuật toán của bạn không chính xác cho năm 2100. vi.wikipedia.org/wiki/Leap_year#Alacticm

2
Tôi biết ;-) Tuy nhiên, điều đó đúng vào năm 2000. Tôi chỉ chơi "phát hiện người bán hàng" ...
Roddy

Phát hiện ra các giáo viên! CƯỜI NGẢ NGHIÊNG.
jcollum

Đúng. Tránh toàn bộ vấn đề, căn cứ vào mảng theo cách bạn muốn.
Loren Pechtel

Tôi sẽ không ngạc nhiên nếu trình biên dịch Pascal trung bình của bạn gán Jan = 0, Dec = 11 khi tạo mã máy :-)

4

Lý do nó bắt đầu từ 0 chứ không phải 1 là vì bạn có thể nghĩ về phần bù là khoảng cách từ đầu bộ nhớ của mảng là bao nhiêu. Nó không nói cho tôi yếu tố thứ 0 - nó nói, hãy cho tôi yếu tố 0 là từ đầu.

Một cách khác để xem xét đó là những cái này tương đương (đối với hầu hết các phần):

array[n]

*(array + n)

Lý do tiêu chuẩn sẽ không bao giờ được thay đổi là vì C đã tồn tại khoảng 40 năm nay. Không có lý do thuyết phục để thay đổi nó và nếu họ đã làm, tất cả các mã hiện có phụ thuộc vào bắt đầu của mảng là 0 sẽ bị phá vỡ.


Trên thực tế, bạn có thể viết lại array[n]như n[array]trong C. Không phải là một ý tưởng tốt để làm điều đó, thật khó hiểu! Nhưng đó là hợp pháp (tốt, ít nhất là lên đến C89) vì danh tính đó ở trên và thực tế là bổ sung là giao hoán.
Donal Fellows

Đó là một cách điên rồ để viết điều đó - một cái gì đó mà nếu bạn thấy trong bất kỳ mã nào bạn phải duy trì sẽ là một dấu hiệu cảnh báo rất lớn. Rất may, tôi đã không chạy qua đó ... nhưng :)
Dennis Munsie

4

Mã bao gồm một số thông tin vị trí ban đầu / vị trí tương đối sạch hơn nhiều với các mảng bắt đầu từ 0.

Ví dụ: Mã để sao chép một vectơ tại một vị trí xác định trong một vectơ lớn hơn là một nỗi đau với các mảng bắt đầu từ 1:

function copyAtPos (dest, vect, i):
    for i from 1 -> vect.length do
        dest[pos+i-1] = vect[i]

Bởi sự đối lập với các mảng bắt đầu từ 0:

function copyAtPos (dest, vect, i):
    for i from 0 -> vect.length-1 do
        dest[pos+i] = vect[i]

Nếu bạn bắt đầu viết công thức kết luận lớn, nó sẽ trở thành bắt buộc.


3

Tại sao không phải 2 hoặc 3 hoặc 20? Nó không giống như có các mảng dựa trên 1 bằng cách nào đó dễ dàng hơn hoặc đơn giản hơn để hiểu các mảng dựa trên không. Để chuyển sang mảng dựa trên 1, mọi lập trình viên ngoài đó sẽ phải học lại cách làm việc với mảng.

Và hơn nữa, khi bạn xử lý bù đắp vào các mảng hiện có, nó cũng có ý nghĩa hơn. Nếu bạn đã đọc 115 byte trong một mảng, bạn sẽ biết đoạn tiếp theo bắt đầu từ 115. Và cứ thế, byte tiếp theo luôn là kích thước của byte bạn đã đọc. Với 1 dựa trên, bạn cần phải thêm một lần.

Và đôi khi bạn cần phải xử lý các khối dữ liệu trong các mảng, ngay cả trong ngôn ngữ mà không có số học con trỏ "thật". Trong java, bạn có thể có dữ liệu trong các tệp ánh xạ bộ nhớ hoặc bộ đệm. Trong trường hợp đó, bạn biết khối i có kích thước * i. Với chỉ số dựa trên 1, nó sẽ ở khối * i + 1.

Với lập chỉ mục dựa trên 1, rất nhiều kỹ thuật sẽ yêu cầu +1 ở mọi nơi.


Tại sao không phải 2 hoặc 3 hoặc 20? Bởi vì 0 là danh tính phụ gia và 1 là danh tính nhân. Họ có ý nghĩa nhất.

3

Sử dụng mảng dựa trên 1, chuyển đổi mảng một chiều thành mảng đa chiều:

int w = 5, h = 5, d = 5;

int[] a1 = new int[w * h * d], new a2 = int[w,h,d];

for (int z = 1; z <= d; z++)

  for (int y = 1; y <= h; y++)

    for (int x = 1; x <= w; x++)

      a1[x + (y - 1) * w + (z - 1) * h] = a2[x,y,z];

Lưu ý rằng các chỉ mục y và z của bạn dựa trên 0 (y - 1, z - 1) ngay cả khi mảng của bạn dựa trên 1. Trong một số trường hợp, bạn không thể tránh các chỉ mục dựa trên 0. Để thống nhất, tại sao không luôn luôn sử dụng các chỉ mục dựa trên 0?


3

Tại sao bạn muốn mảng bắt đầu tại một?

Khi bạn nói a[x][y], trình biên dịch sẽ dịch nó thành : a+(x*num_cols+y). Nếu mảng bắt đầu tại một, điều này sẽ trở thành a+(x*num_cols+y-1). Đây sẽ là một hoạt động số học bổ sung mỗi khi bạn muốn truy cập một phần tử mảng. Tại sao bạn muốn làm chậm chương trình?


1
thực tế, nó sẽ phải trở thành + ((x - 1) * num_cols) + y - 1) - cả x và y sẽ bắt đầu từ 1.
Dennis Munsie

2

Tôi sẽ bước ra một chi ở đây và đề xuất một cái gì đó khác với một mảng 'khóa' số nguyên.

Tôi nghĩ rằng đồng nghiệp của bạn đang tạo ra một bản đồ một "tập hợp" trong thế giới vật lý nơi chúng ta luôn bắt đầu đếm từ 1. Tôi có thể hiểu điều này, khi bạn không làm gì lạ mắt, thật dễ hiểu một số mã khi bạn được ánh xạ 1 đến 1 giữa phần mềm và thế giới vật lý.

Đề xuất của tôi

Không sử dụng mảng dựa trên số nguyên cho bất cứ thứ gì bạn đang lưu trữ, nhưng sử dụng một số loại từ điển hoặc cặp giá trị khóa khác. Những bản đồ này tốt hơn với cuộc sống thực khi bạn không bị ràng buộc bởi một số nguyên tùy ý. Điều này có vị trí của nó và tôi khuyên bạn nên sử dụng nó nhiều nhất có thể do lợi ích của các khái niệm ánh xạ 1 đến 1 giữa phần mềm và thế giới vật lý.

tức là kvp['Name Server'] = "ns1.example.com"; (Đây chỉ là một trong số một triệu ví dụ có thể).

Khiếu nại

Điều này chắc chắn không hoạt động khi bạn đang làm việc với các khái niệm dựa trên toán học, về cơ bản vì toán học gần với việc triển khai thực tế của máy tính. Sử dụng các bộ kvp sẽ không giúp được gì ở đây, nhưng thực sự sẽ làm mọi thứ rối tung lên và khiến nó trở nên rắc rối hơn. Tôi đã không nghĩ qua tất cả các trường hợp góc trong đó một cái gì đó có thể hoạt động tốt hơn như kvp hoặc như một mảng.

Ý tưởng cuối cùng là sử dụng các mảng dựa trên số 0 hoặc các cặp giá trị khóa có ý nghĩa, hãy nhớ rằng khi bạn chỉ có một cái búa, mọi vấn đề bắt đầu trông giống như một cái đinh ...


2

Cá nhân, một đối số là khi xem các chỉ mục mảng là offset. Nó chỉ có ý nghĩa.

Người ta có thể nói rằng nó là phần tử đầu tiên, nhưng phần bù của phần tử đầu tiên so với gốc của mảng là bằng không. Như vậy, lấy nguồn gốc mảng và thêm số 0 sẽ mang lại phần tử đầu tiên.

Vì vậy, trong tính toán, việc thêm số 0 để tìm phần tử đầu tiên dễ dàng hơn là thêm phần tử và sau đó loại bỏ phần tử.

Tôi nghĩ rằng bất cứ ai đã làm một số công cụ cấp thấp hơn luôn luôn nghĩ rằng cơ sở không có cách nào. Và những người bắt đầu hoặc đã quen với trình độ cao hơn thường không lập trình thuật toán có thể muốn có một hệ thống cơ sở. Hoặc có thể chúng ta chỉ thiên vị bởi những kinh nghiệm trong quá khứ.


Chính xác - về cơ bản, đó là một quy ước nằm xung quanh các ngôn ngữ cấp thấp hơn.

2

Hai lý do nghiêm trọng duy nhất đối với các chỉ số dựa trên 0 được sử dụng thay vì các chỉ số dựa trên 1 dường như tránh việc điều chỉnh lại rất nhiều lập trình viêncho sự tương thích ngược .

Tôi không thấy bất kỳ đối số nghiêm trọng nào khác chống lại các chỉ số dựa trên 1 trong tất cả các câu trả lời bạn nhận được.

Trong thực tế, các chỉ số tự nhiên dựa trên 1 , và đây là lý do tại sao.

Đầu tiên, chúng ta phải hỏi: mảng có đến từ đâu không? Họ có tương đương trong thế giới thực? Câu trả lời là có: chúng là cách chúng ta mô hình hóa các vectơ và ma trận trong khoa học máy tính. Tuy nhiên, vectơ và ma trận là các khái niệm toán học đã sử dụng các chỉ mục dựa trên 1 trước thời đại máy tính (và chủ yếu vẫn sử dụng các chỉ mục dựa trên 1 ngay bây giờ).

Trong thế giới thực, các chỉ số là 1 cơ sở.

Như Thomas đã nói ở trên, các ngôn ngữ sử dụng các chỉ số 0-căn cứ trên thực tế là sử dụng các giá trị bù trừ , không phải các chỉ số. Và các nhà phát triển đang sử dụng các ngôn ngữ này nghĩ về việc bù đắp , không phải chỉ số. Điều này sẽ không thành vấn đề nếu mọi thứ được nêu rõ ràng, nhưng chúng thì không. Rất nhiều nhà phát triển sử dụng offset vẫn nói về các chỉ số. Và rất nhiều nhà phát triển sử dụng các chỉ số vẫn không biết rằng C, C ++, C #, ... sử dụng offset.

Đây là một vấn đề từ ngữ .

(Lưu ý về giấy Diskstra của - Nó nói một cách chính xác những gì tôi đã nói ở trên : nhà toán học tôi sử dụng 1 dựa trên chỉ số Nhưng Diskstra nghĩ rằng matematicians. Không nên sử dụng chúng bởi vì một số biểu hiện sau đó sẽ là xấu xí (ví dụ .: 1 <= n <= 0 ). Chà, không chắc anh ta đã đúng về điều đó - thực hiện một sự thay đổi mô hình như vậy để tránh những chuỗi trống đặc biệt đó có vẻ rất nhiều rắc rối cho một kết quả nhỏ ...)


2
Các nhà toán học không phải lúc nào cũng sử dụng các chỉ số dựa trên 1. Tôi đã thấy x0 sử dụng nhiều lần cho giá trị ban đầu của chuỗi. Nó phụ thuộc vào cái nào thuận tiện hơn.

2

Bạn đã bao giờ cảm thấy khó chịu bởi "thế kỷ 20" thực sự đề cập đến những năm 1900 chưa? Vâng, đó là một sự tương tự tốt cho những điều tẻ nhạt mà bạn luôn phải đối phó khi sử dụng mảng dựa trên 1.

Hãy xem xét một tác vụ mảng phổ biến như phương thức đọc .net IO.stream:

int Read(byte[] buffer, int offset, int length)

Dưới đây là những gì tôi khuyên bạn nên làm để thuyết phục bản thân các mảng dựa trên 0 là tốt hơn:

Trong mỗi kiểu lập chỉ mục, hãy viết một lớp BufferedStream hỗ trợ đọc. Bạn có thể thay đổi định nghĩa của chức năng Đọc (ví dụ: sử dụng giới hạn dưới thay vì bù) cho các mảng dựa trên 1. Không cần bất cứ điều gì lạ mắt, chỉ cần làm cho nó đơn giản.

Bây giờ, một trong những thực hiện đó là đơn giản hơn? Cái nào có độ lệch +1 và -1 được rắc ở đây và kia? Đó là những gì tôi nghĩ. Trong thực tế, tôi sẽ lập luận rằng các trường hợp duy nhất mà kiểu lập chỉ mục không thành vấn đề là khi nào bạn nên sử dụng thứ gì đó không phải là một mảng, như Set.


Đó là một sự tương tự xấu nhầm lẫn logic số nguyên với dấu phẩy động.

2

Đó là vì cách các mảng được xây dựng. Nó không có ý nghĩa nhiều đối với họ để bắt đầu từ một. Mảng là một địa chỉ cơ sở trong bộ nhớ, kích thước và chỉ mục. Để truy cập phần tử thứ n, đó là:

base + n * element_size

Vì vậy, 0 rõ ràng là phần bù đầu tiên.


1

Thực tế, có một số cách khác nhau để thực hiện điều này:

  • Chỉ mục mảng dựa trên 0
  • Chỉ mục mảng dựa trên 1
  • hoặc 0 hoặc 1 mảng dựa trên (như VB 6.0 ... điều này thực sự khủng khiếp)

Cuối cùng, tôi không nghĩ vấn đề là liệu ngôn ngữ sử dụng mảng dựa trên 0 hay 1. Nhưng, tôi nghĩ sự lựa chọn tốt nhất là sử dụng các mảng dựa trên 0, vì lý do đơn giản là hầu hết các lập trình viên đã quen với quy ước đó và nó phù hợp với phần lớn mã đã được viết.

Tuy nhiên, cách duy nhất bạn có thể thực sự sai, là không nhất quán như Visual Basic. Cơ sở mã mà tôi hiện đang duy trì được phân chia giữa các mảng dựa trên 0 và 1; và nó cực kỳ khó khăn để tìm ra cái nào là cái nào. Điều này dẫn đến một vòng lặp khó chịu cho vòng lặp:

dim i as integer, lb as integer, ub as integer
lb = LBound(array)
ub = UBound(array)
for i = lb to ub
       '...
next

hahaha Tôi nhớ điều đó, người đàn ông đã hút ...
Dan Rosenstark

Tôi nghĩ tôi nhớ thậm chí có các mảng bắt đầu bằng số âm. Chỉ là một trong nhiều lý do tôi tránh xa VB.

1

Không là tự nhiên khi nói về vị trí của một mục trong bộ sưu tập tuyến tính.

Hãy nghĩ về một kệ đầy sách - cuốn sách đầu tiên được đặt phẳng với bức tường bên của kệ - đó là vị trí số không.

Vì vậy, tôi đoán nó phụ thuộc vào việc bạn coi các chỉ số mảng là một phương tiện để tìm kiếm mọi thứ hoặc đề cập đến mọi thứ.


1

Tôi thích chỉ số dựa trên 0 vì modulo (và toán tử AND khi được sử dụng cho modulo) luôn trả về 0 cho một số giá trị.

Tôi thường thấy mình sử dụng các mảng như thế này:

int blah = array[i & 0xff];

Tôi thường nhận được loại mã sai khi sử dụng 1 chỉ số dựa trên.


1

Thật khó để bảo vệ cơ sở 0 mà không lập trình nhiều mã dựa trên mảng, chẳng hạn như tìm kiếm chuỗi và các thuật toán sắp xếp / hợp nhất khác nhau hoặc mô phỏng các mảng đa chiều trong một mảng một chiều. Fortran dựa trên 1 và bạn cần rất nhiều cà phê để thực hiện đúng loại mã này.

Nhưng nó đi xa hơn thế. Đó là một thói quen tinh thần rất hữu ích để có thể suy nghĩ về độ dài của một cái gì đó hơn là các chỉ số của các yếu tố của nó. Ví dụ, khi thực hiện đồ họa dựa trên pixel, sẽ rõ ràng hơn nhiều khi nghĩ tọa độ là rơi giữa các pixel thay vì trên chúng. Bằng cách đó, một hình chữ nhật 3x3 chứa 9 pixel, không phải 16.

Một ví dụ xa hơn một chút là ý tưởng nhìn về phía trước trong phân tích cú pháp hoặc in các tổng số phụ trong một bảng. Cách tiếp cận "thông thường" cho biết 1) lấy ký tự, mã thông báo hoặc hàng bảng tiếp theo và 2) quyết định phải làm gì với nó. Cách tiếp cận nhìn về phía trước cho biết 1) giả sử bạn có thể nhìn thấy nó và quyết định xem bạn có muốn không và 2) nếu bạn muốn, hãy "chấp nhận" nó (cho phép bạn xem cái tiếp theo). Sau đó, nếu bạn viết mã giả, nó đơn giản hơn nhiều.

Một ví dụ khác là cách sử dụng "goto" trong các ngôn ngữ mà bạn không có lựa chọn nào, chẳng hạn như các tệp bó MS-DOS. Cách tiếp cận "thông thường" là gắn nhãn vào các khối mã sẽ được thực hiện và gắn nhãn như vậy. Thông thường một cách tiếp cận tốt hơn là đặt nhãn ở cuối các khối mã, với mục đích bỏ qua chúng. Điều này làm cho nó "có cấu trúc" và dễ dàng sửa đổi hơn nhiều.


1

Nó chỉ là như vậy, và đã được nhiều năm. Để thay đổi nó, hoặc thậm chí để tranh luận về nó, cũng vô nghĩa như thay đổi hoặc tranh luận về việc thay đổi đèn giao thông. Hãy tạo màu xanh = dừng, đỏ = đi.

Xem xét các thay đổi được thực hiện theo thời gian trong Công thức số cho C ++. Họ đã sử dụng macro để lập chỉ mục dựa trên 1 giả, nhưng trong phiên bản năm 2001 đã từ bỏ và gia nhập đàn. Có thể có tài liệu khai sáng về lý do đằng sau này tại trang web của họ www.nr.com

BTW, cũng gây phiền nhiễu là các biến thể của việc chỉ định một phạm vi ra khỏi một mảng. Ví dụ: trăn so với IDL; [100: 200] so với [100: 199] để nhận 100 phần tử. Chỉ cần học những điều kỳ quặc của từng ngôn ngữ. Để thay đổi một ngôn ngữ theo cách này phù hợp với ngôn ngữ kia sẽ gây ra sự chửi rủa và nghiến răng như vậy, và không giải quyết được bất kỳ vấn đề thực sự nào.


1

Tôi thích các mảng dựa trên 0 bởi vì, như được đề cập bởi những người khác, nó làm cho toán học dễ dàng hơn. Ví dụ: nếu chúng ta có mảng 1 chiều gồm 100 phần tử mô phỏng lưới 10x10, thì chỉ số mảng i của phần tử trong hàng r, col c là gì:

Dựa trên 0: i = 10 * r + c
Dựa trên 1: i = 10 * (r - 1) + c

Và, với chỉ số i, quay trở lại hàng và cột là:

Dựa trên 0: c = i% 10
         r = sàn (i / 10)
Dựa trên 1: c = (i - 1)% 10 + 1
         r = trần (i / 10)

Cho rằng toán học ở trên rõ ràng phức tạp hơn khi sử dụng mảng dựa trên 1, có vẻ hợp lý khi chọn mảng dựa trên 0 làm tiêu chuẩn.

Tuy nhiên, tôi nghĩ rằng ai đó có thể cho rằng logic của tôi là thiếu sót vì tôi cho rằng sẽ có lý do để thể hiện dữ liệu 2D trong mảng 1D. Tôi đã gặp phải một số tình huống như vậy trong C / C ++, nhưng tôi phải thừa nhận rằng việc cần thực hiện các tính toán như vậy là hơi phụ thuộc vào ngôn ngữ. Nếu các mảng thực sự thực hiện tất cả toán học chỉ mục cho máy khách mọi lúc, thì trình biên dịch có thể chỉ cần chuyển đổi truy cập mảng dựa trên M của bạn thành 0 dựa trên thời gian biên dịch và ẩn tất cả các chi tiết triển khai này khỏi người dùng. Trong thực tế, bất kỳ hằng số thời gian biên dịch nào cũng có thể được sử dụng để thực hiện cùng một tập hợp các hoạt động, mặc dù các cấu trúc như vậy có thể sẽ dẫn đến mã không thể hiểu được.

Có lẽ một lập luận tốt hơn sẽ là việc giảm thiểu số lượng các hoạt động chỉ mục mảng trong một ngôn ngữ với các mảng dựa trên 1 sẽ yêu cầu phân chia số nguyên được thực hiện bằng cách sử dụng hàm trần. Tuy nhiên, từ góc độ toán học, phép chia số nguyên sẽ trả về d phần dư r, trong đó d và r đều dương. Do đó, các mảng dựa trên 0 nên được sử dụng để đơn giản hóa toán học.

Ví dụ: nếu bạn đang tạo bảng tra cứu với N phần tử, chỉ mục gần nhất trước giá trị hiện tại vào mảng cho giá trị x sẽ là (xấp xỉ, bỏ qua các giá trị trong đó kết quả là một số nguyên trước khi làm tròn):

Dựa trên 0 với sàn: sàn ((N - 1) * x / xRange)
1 dựa trên sàn: sàn ((N - 1) * x / xRange) + 1
Dựa trên 1 với trần: trần ((N - 1) * x / xRange)

Lưu ý rằng nếu quy ước làm tròn tiêu chuẩn được sử dụng, các mảng dựa trên 1 yêu cầu một thao tác bổ sung, điều này là không mong muốn. Loại toán học này không thể bị ẩn bởi trình biên dịch, vì nó đòi hỏi kiến ​​thức cấp thấp hơn về những gì đang xảy ra đằng sau hậu trường.


Đó là một lý do chính đáng cho đến khi bạn có các ngôn ngữ cấp cao hơn hỗ trợ các mảng đa chiều.

1

Tôi cá là lập trình viên chỉ thấy khó chịu với tính trực giác của một mảng dựa trên 0 trong suy nghĩ hàng ngày và đang tranh cãi về một phương tiện trực quan hơn để mô tả mảng. Tôi thấy thật trớ trêu khi con người chúng ta dành quá nhiều thời gian để đến với "các lớp" để chúng ta có thể mô tả mọi thứ theo cách nhân văn hơn trong mã của chúng ta, nhưng sau đó khi nhìn vào các mảng 0 vs 1, chúng ta dường như bị treo lên logic của nó một mình.

Theo như máy tính có liên quan và về mặt toán học 0 có lẽ sẽ tốt hơn, nhưng tôi cảm thấy một điểm đang bị bỏ lỡ ở đây. Nếu chúng ta muốn mô tả mọi thứ theo cách nhân văn hơn (ví dụ như các lớp học), tại sao chúng ta lại không muốn điều tương tự cho các phần khác của ngôn ngữ? Có phải điều đó không hợp lý hoặc hợp lệ (hoặc ưu tiên cao hơn cho vấn đề đó ...) để làm cho ngôn ngữ trở nên dễ hiểu và dễ sử dụng hơn đối với con người và do đó, bằng cách mở rộng, ít có xu hướng tạo ra lỗi logic và dễ bị lỗi hơn để sản xuất nhanh hơn một sáng tạo có thể sử dụng. Ví dụ về PHP:

array(1 => 'January', 'February', 'March');

đưa ra một mảng dựa trên mỗi yêu cầu của chúng tôi.

Tại sao không có định mức:

array('January', 'February', 'March');

Và ngoại lệ là:

array(0 => 'Value for scenario where 0 *has* to be used as the key',
      'value2', 'value3');

Trong trường hợp nói PHP, đặt cược của tôi là 80% thời gian mảng 1 dựa trên cú pháp mặc định sẽ làm giảm lỗi logic trong các trường hợp sử dụng trong thế giới thực hoặc ít nhất là không gây ra nhiều hơn, trong khi làm cho nó rất nhiều dễ dàng hơn trên bộ mã hóa để sản xuất mã có thể sử dụng nhanh hơn. Hãy nhớ rằng, tôi cho rằng vẫn sẽ có tùy chọn, mảng (0 => 'value') khi cần, nhưng cũng giả sử phần lớn thời gian thực tế để có một cái gì đó gần với mô tả thế giới thực.

Điều này thực sự không có vẻ quá xa vời với một yêu cầu khi nhìn vào nó từ quan điểm đó. Khi tiếp cận một giao diện, có thể là hệ điều hành hoặc ngôn ngữ cho lập trình viên, càng gần với suy nghĩ và thói quen của con người chúng ta thiết kế nó, càng hạnh phúc hơn trong hầu hết các trường hợp chúng ta sẽ và ít hiểu lầm hơn giữa con người và máy tính (logic của con người- lỗi), và sản xuất nhanh hơn, vv chúng ta sẽ có. Nếu 80% thời gian trong thế giới thực tôi mô tả mọi thứ bằng 1 khi lập danh sách hoặc đếm, thì máy tính sẽ lý tưởng diễn giải ý nghĩa của tôi thành cách nó hiểu với càng ít thông tin hoặc thay đổi từ cách mô tả thông thường của tôi càng tốt. Nói tóm lại, chúng ta có thể mô hình hóa thế giới thực càng gần, chất lượng trừu tượng càng tốt. Vì vậy, những gì anh ta muốn không có nghĩa là ngu ngốc vì đó là mục tiêu cuối cùng và sẽ là bằng chứng cho sự cần thiết phải trừu tượng hơn. Cuối cùng, máy tính vẫn có thể xem nó như là một cách sử dụng đặc biệt của mảng dựa trên 0. Tôi không quan tâm đến việc máy tính diễn giải nó như thế nào miễn là nó đơn giản và trực quan hơn để tôi mô tả những gì tôi muốn với nó với ít lỗi hơn theo thời gian.

Vì vậy, đó là hai xu của tôi. Tôi thực sự nghi ngờ những gì anh ấy nói, hoặc những gì được giải thích, là những gì anh ấy có nghĩa. Điều anh ta có lẽ có nghĩa là, "Tôi ghét có một cách ít trực quan hơn để nói với máy tính những gì tôi muốn." :) Đừng tất cả chúng ta? cười ngả nghiêng.


1

Có thể nếu bạn cẩn thận trong khi viết mã "của riêng bạn". Bạn có thể giả sử chỉ mục của bạn bắt đầu từ n cho tất cả n> = 0 và lập trình tương ứng.

Về tiêu chuẩn, Borealid có một lập luận tuyệt vời.

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.