Nguồn gốc của việc đếm từ số 0 trong các ngôn ngữ lập trình là gì?


8

Đây là một câu hỏi mà tôi đã tự hỏi (và được hỏi) trong một thời gian dài.

Trong (hầu hết? Tất cả?) Ngôn ngữ lập trình, một chỉ mục bắt đầu từ 0 cho một mảng, chuỗi, v.v. Tôi nhận ra nó trở thành quy ước theo thời gian, được chấp nhận bằng nhiều ngôn ngữ, nhưng ai cũng có thể chỉ ra nguồn gốc của điều này?

Tôi nghĩ, có lẽ, nó phải làm với tất cả bắt nguồn từ nhị phân. Nhưng tôi không chắc chắn về ý tưởng mang đến sự cần thiết trong hệ thống thập phân - tại sao không bắt đầu một chỉ mục từ 1?

Có ai có kiến ​​thức lịch sử về ngôn ngữ lập trình trong đó quyết định bắt đầu lập chỉ mục ở mức 0 có thể được giải thích không?

Cảm ơn bạn!

EDIT: Các tác phẩm của Dijkstra hữu ích hơn nữa từ quan điểm toán học, nhưng ngay cả ông cũng lưu ý, không phải tất cả các ngôn ngữ đều được lập chỉ mục bằng không. Giải thích của WBT cũng có lý do tại sao một người sẽ bắt đầu bằng 0 dựa trên địa chỉ bộ nhớ. (Tôi biết một số ngôn ngữ xử lý lập chỉ mục hơi khác nhau dựa trên thao tác mảng.)

Tôi không nhất thiết phải tìm kiếm lý do tại sao (điều mà tôi rất đánh giá cao vì nó giúp hiểu thêm) nhưng nhiều hơn nữa khi điều này trở thành quy ước và / hoặc liệu nó có thể được truy tìm đến một ngôn ngữ cụ thể.

Vì vậy, ví dụ trong K & R's C, khi thảo luận về chỉ mục mảng, K hoặc R thực tế giải thích, "Các chỉ số mảng luôn bắt đầu từ 0 trong C ..." (trang 22) Sau đó, khi thảo luận về một hàm để xử lý ký tự mảng, "... một thiết kế hữu ích hơn sẽ trả về độ dài của dòng hoặc bằng 0 nếu gặp phải cuối tệp. Zero là trả về cuối tệp có thể chấp nhận được vì nó không bao giờ là độ dài dòng hợp lệ." (trang 127)

Dựa trên K & R, tôi tập hợp a) quy ước được thông qua từ nơi khác, vì vậy C không phải là nguồn cảm hứng cho việc lập chỉ mục bằng 0 và b) có thể có những lý do sâu xa hơn cho việc sử dụng nó dựa trên ví dụ thứ hai. Tôi biết K & R được đánh giá cao về văn xuôi rõ ràng, vì vậy đó là một lý do khác mà tôi đưa nó vào, để đưa ra một ví dụ về những gì tôi đã hy vọng một ngôn ngữ tài liệu khác sẽ làm để giải thích lý do đằng sau việc lập chỉ mục bằng không.

Tôi nghĩ rằng cả WBT và btilly đều đưa ra những lý do tốt như nhau; Tôi tự hỏi liệu có ai biết những ngôn ngữ cũ (tiền C?) Đã ghi lại quyết định thiết kế không. Và đồng thời tôi nhận ra thông tin như vậy có thể không tồn tại.


3
Câu trả lời đơn giản là khi mảng là con trỏ, có cơ sở 0 là hợp lý nhất. Sau đó myarray [0] và myarray + 0 là cùng một yếu tố và myarray [1] và myarray + 1, v.v ... Hãy nghĩ về nó như một sự bù đắp từ đầu. Một câu trả lời phức tạp hơn có thể sắp được đưa ra vì vậy tôi chỉ thêm nó dưới dạng một nhận xét :)

@ThomasH Điều đó không hoàn toàn "cơ sở 0." Cơ sở đề cập đến có bao nhiêu biểu tượng duy nhất đại diện cho các giá trị khác nhau trước khi thêm một vị trí mới trong số. Cơ sở có thể được tìm thấy bằng cách tìm ra 10-1 là gì trong hệ thống đó. Cơ sở 10 (thập phân), cơ sở 2 (nhị phân) và cơ sở 16 (hex) được biết đến rộng rãi nhất.
WBT

1
@WBT Bạn sẽ nghĩ rằng nếu bạn chỉ đọc tiêu đề.

@ user6292850 Tôi đồng ý đây là một tài liệu tham khảo hữu ích, nhưng tôi không nghĩ đó là một bản sao.
WBT

3
Dijkstra đã viết điều này về các chỉ số bằng không: cs.utexas.edu/users/EWD/transcrip/EWD08xx/EWD831.html
Thomas Eding

Câu trả lời:


12

Đó là về sự bù đắp. Bạn có một địa chỉ, trỏ đến vị trí trong bộ nhớ nơi mảng bắt đầu. Sau đó, để truy cập bất kỳ phần tử nào, bạn nhân chỉ số mảng với kích thước của phần tử và thêm nó vào địa chỉ bắt đầu, để tìm địa chỉ cho phần tử đó.

Phần tử đầu tiên nằm ở điểm bắt đầu, vì vậy bạn nhân kích thước của phần tử với 0 để lấy số 0 , đó là những gì bạn thêm vào địa chỉ bắt đầu để tìm vị trí của phần tử đầu tiên.

Quy ước lan rộng vì các lập trình viên bắt đầu làm việc trong các ngôn ngữ cấp thấp, nơi các địa chỉ bộ nhớ bị thao túng trực tiếp và trong hầu hết các trường hợp xây dựng từ đó, duy trì cùng một quy ước ở mỗi bước để họ không phải học lại hoặc dễ mắc lỗi khi chuyển đổi giữa các quy ước. Điều quan trọng là phải hiểu cách hoạt động của địa chỉ này đặc biệt là khi làm việc với các ngôn ngữ cấp thấp hơn. Tôi đồng ý đây có thể là một trở ngại cho những người lần đầu tiên học lập trình bằng ngôn ngữ cấp cao hơn.

Các bài viết trên Wikipedia về chủ đề này cũng trích dẫn một hướng dẫn máy thường được sử dụng khi làm việc "ngược" và phát hiện khi kết thúc một vòng lặp, cụ thể là "sụt lần và nhảy nếu bằng không."

Một ngoại lệ: MATLAB và một số ngôn ngữ khác đã bắt kịp xu hướng và đi kèm với chỉ số bắt đầu từ 1, rõ ràng là ấn tượng rằng nó sẽ là ngôn ngữ lập trình đầu tiên cho nhiều người dùng mục tiêu của họ và đối với những người đó, bắt đầu bằng 1 cảm giác trực quan. Điều này gây ra một số sự thất vọng cho các lập trình viên (tương đối nhỏ của?), Những người thường xuyên chuyển đổi giữa các ngôn ngữ lập trình bắt đầu đếm ở các giá trị khác nhau.


1
Đúng. Không ai có bất kỳ liên hệ nào với nhà lắp ráp sẽ hỏi câu hỏi này :)
Martin James

4

Câu lệnh "Trong (hầu hết? Tất cả?) Ngôn ngữ lập trình, một chỉ mục bắt đầu từ 0" đơn giản là không chính xác. Những ngôn ngữ có di sản chính thức hoặc không chính thức từ C tuân theo quy ước này. Những người khác có thể không.

C đã làm theo cách đó bởi vì C về cơ bản được dự định là một trình biên dịch "cấp cao". Nó đặt một gánh nặng công bằng cho khối lượng công việc lên lập trình viên, nơi các ngôn ngữ khác có trình biên dịch và máy thực hiện công việc nặng nhọc. Tại thời điểm C được phát triển, việc đếm dựa trên 1 là chuẩn mực, nhưng yêu cầu trình biên dịch phải theo dõi phần bổ sung ngớ ngẩn đó được coi là quá nhiều công việc cho trình biên dịch.

C ++ đã nhận được nó từ C vì yêu cầu C ++ phải tương thích ngược (một số người có thể nói là tương thích với lỗi) với C. Java đã lấy nó từ C. Các ngôn ngữ được lập trình viên C phát triển mà không có sự tiếp xúc đáng kể với bất kỳ thứ gì khác được sao chép C, bởi vì chúng muốn được phổ biến với các lập trình viên C khác hoặc họ không biết cách nào khác để làm điều đó.

FORTRAN, trước hầu hết mọi thứ khác, bắt đầu từ 1, bởi vì các kỹ sư, nhà toán học và nhà khoa học đã đếm bắt đầu từ 1 cho milimet. (Điều này cho phép một thuật toán rất ngắn gọn, rất hay cho vấn đề 8-Queen.) MATLAB sao chép FORTRAN, vì nó nhắm đến gần như chính xác cùng một cộng đồng người dùng.

PASCAL thực sự yêu cầu lập trình viên nói nơi anh ta bắt đầu và kết thúc, cho phép một người xác định, ví dụ, và mảng có chỉ số chạy từ, giả sử, -7 đến +7. Ada đã theo PASCAL. (Đề cập Ada phải tốt cho ít nhất ba lượt tải xuống ngay tại đó.)

Tôi tin rằng COBOL bắt đầu từ 1, nhưng tôi không nhớ chắc chắn, và tôi không có ý định làm mới một số ký ức rất đau đớn, bởi vì kế toán, như các kỹ sư, nhà khoa học và nhà toán học, bắt đầu đếm từ 1.

Đó là hồi ức xa xôi của tôi rằng PL / Tôi cho phép bạn bắt đầu và dừng lại bất cứ nơi nào bạn thích. Tiết lộ đầy đủ: Tôi chưa bao giờ thực hiện mã hóa PL / I, chỉ đọc lướt qua một cuốn sách và tôi không có ý định thay đổi điều đó.

Tôi chưa bao giờ sử dụng mảng trong GPSS (gói mô phỏng sự kiện rời rạc của IBM), trong thời gian tiếp xúc ngắn với nó, vì vậy tôi không thể cho bạn biết GPSS đã làm như thế nào.

Ngôn ngữ hội thường bắt đầu từ 0 vì các mảng được xác định theo truyền thống theo địa chỉ bắt đầu và phần bù từ địa chỉ bắt đầu. . số không sẽ vứt đi một nửa kích thước có thể của cái bàn và cái bàn đó CẦN phải lớn.)


0

Cố gắng trả lời ngắn gọn.

Đếm từ số 0 là phổ biến không chỉ trong ngôn ngữ lập trình mà trong toán học nói chung hơn.

Đếm cũ hơn nhiều so với số không. Vì ký hiệu số 0 và vị trí được phát minh, mọi người đều đếm 10, 100, 1000, v.v. từ 0: đó là chữ số thấp nhất mới. Việc đếm các đơn vị từ 0 cũng mang lại một vài lợi thế nhất quán, đáng chú ý là các khoảng thời gian nửa mở và mảng (đa chiều). Để biết thêm chi tiết và ví dụ, hãy xem các liên kết ở phía bên phải và https://en.wikipedia.org/wiki/Zero-basing_numbering


1
Các số đi từ 0 đến 9 chứ không phải từ 1 đến 10.
Ignacio Soler Garcia

Theo kinh nghiệm của tôi, các chỉ số đi từ 1 đến n phổ biến hơn các chỉ số đi từ 0 đến n-1 trong toán học.
CodeInChaos

-3

Mọi quy ước có thể có đã được thử. Việc đếm từ quy ước 0 đã trở nên chiếm ưu thế vì các lựa chọn thay thế có xu hướng dễ bị tai nạn hơn.

Xem https://www.cs.utexas.edu/users/EWD/transcrip/EWD08xx/EWD831.html để biết một lời giải thích tại sao phiên bản này hoạt động tốt hơn.


2
Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi. - Từ đánh giá
Vinoth Krishnan

6
"Mọi quy ước đếm có thể đã được thử." Có bao gồm cái bắt đầu từ - e và tăng theo đơn vị π không?
WBT
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.