Có ngôn ngữ “c-like” hoặc không “c-like” phổ biến nào khác với vị trí mảng chỉ mục không? [đóng cửa]


76

Ngôn ngữ lập trình C được biết đến như một ngôn ngữ mảng không chỉ số. Mục đầu tiên trong một mảng có thể truy cập được bằng cách sử dụng 0. Ví dụ: double arr[2] = {1.5,2.5}Mục đầu tiên trong mảng arrnằm ở vị trí 0. arr[0] === 1.51 chỉ mục dựa trên ngôn ngữ lập trình nào?

Tôi đã nghe nói về các ngôn ngữ này bắt đầu từ 1 thay vì 0 để truy cập mảng: Algol, Matlab, Action !, Pascal, Fortran, Cobol. Cái này đã hoàn thành chưa?

Cụ thể, một mảng dựa trên 1 sẽ truy cập mục đầu tiên bằng 1, không phải bằng 0.


8
Đây hẳn là một wiki
Austin Salonen 30/09/09

48
Tại sao mọi người bỏ phiếu để đóng cho "không phải là một câu hỏi thực sự"? Nó khá rõ ràng là một câu hỏi thực sự. Nó có thể không phải là cái hay nhất mà trang web từng thấy, và nó có thể gần xứng đáng, nhưng chắc chắn không phải vì nó "không phải là một câu hỏi thực sự."
Chris Lutz 30/09/09

2
Hầu hết mọi thứ từ trước C, vì toàn bộ thứ được lập chỉ mục Zero bắt đầu như một tạo tác triển khai assmebler / C (vì con người thực không được tính từ Zero). Vì vậy (các) ngôn ngữ Cơ bản, COBOL, Fortran và hầu hết các ngôn ngữ có nguồn gốc từ chúng.
RBarryYoung 30/09/09

1
Tôi đoán tiêu đề không được định dạng chính xác như một câu hỏi, nhưng phần nội dung chắc chắn là như vậy. Làm thế nào đây không phải là một câu hỏi thực sự?
Samantha Branham

7
Chris Lutz: RE: Đắng; chưa thực sự cay đắng, hãy chỉ nói "cáu kỉnh và bất mãn", đặc biệt. w / Bỏ phiếu kín trên trang web này. RE: "Thực phẩm cho lập trình"; bạn biết đấy, tôi đã dùng cái tên này như một trò đùa, nhưng trên thực tế, đây là một chủ đề gần như giống hệt với chủ đề này đã mở được một năm: stackoverflow.com/questions/92257/programmers-food . Đây là điều làm tôi bất bình, việc bỏ phiếu kín ở đây không liên quan gì đến các câu hỏi lập trình thực sự và mọi thứ liên quan đến văn hóa con của một lập trình viên nhất định được trang web này soạn thảo. Một nền văn hóa phụ vừa mang tính chất dân tộc vừa có tư tưởng gần gũi.
RBarryYoung

Câu trả lời:


63

Một danh sách có thể được tìm thấy trên wikipedia .

ALGOL 68
APL
AWK
CFML
COBOL
Fortran
FoxPro
Julia
Lua
Mathematica
MATLAB
PL/I
Ring
RPG
Sass
Smalltalk
Wolfram Language
XPath/XQuery

10
Một cái gì đó trên wikipedia không hoàn toàn chính xác ?? Nói không quá!
davr 30/09/09

3
Lưu ý rằng nó nói "chỉ mục cơ sở mặc định", vì vậy phần đó là chính xác. Tuy nhiên, điều không chính xác là chỉ số cơ sở mặc định trong BASIC vẫn là 0, không phải là một - vì vậy tôi đã sửa điều đó.
Pavel Minaev 30/09/09

5
Trên thực tế, BASIC thay đổi rất nhiều , đặc biệt là về điểm này.
RBarryYoung

9
@Yannick: Bạn biết Wikipedia có thể chỉnh sửa bởi bất kỳ ai, phải không? Tại sao phàn nàn về sự không chính xác; chỉ cần sửa chúng!
DisgruntledGoat

3
@ ST3, đó có thể là cách nó hoạt động ngầm, nhưng PHP vẫn gọi chúng là mảng và hành vi cơ bản của chúng (sử dụng chúng mà không chỉ định khóa) hoạt động giống như mảng.
Tynach

20

Fortran bắt đầu từ 1. Tôi biết điều đó bởi vì bố tôi đã từng lập trình Fortran trước khi tôi sinh ra (bây giờ tôi 33 tuổi) và ông thực sự chỉ trích các ngôn ngữ lập trình hiện đại bắt đầu từ 0, nói rằng nó không tự nhiên, không phải cách con người nghĩ, không giống như toán học, và Sớm.

Tuy nhiên, tôi thấy mọi thứ bắt đầu từ con số 0 khá tự nhiên; ngôn ngữ lập trình thực đầu tiên của tôi là C và * (ptr + n) sẽ không hoạt động tốt như vậy nếu n không bắt đầu bằng 0!


12
+1: nhưng nó thực sự dành cho bố bạn, người đã bắt đầu lập trình ở Fortran cùng thời điểm với tôi. Tôi mong rằng khi anh ấy dạy bạn đếm, anh ấy đã dạy bạn những thứ như 1 con bò, 2 con bò, 3 con bò ... Bây giờ ai mà không tự nhiên!
hiệu suất cao

6
@High Performance Mark Tất nhiên là những con bò không tự nhiên. Chúng nên bắt đầu từ 0 con bò.
abel

3
Khi đếm các mục, thậm chí không phải lập trình viên C nói rằng có 0 mục, nếu có 1 trong số chúng! Nhưng mục đầu tiên có thể hợp lệ ở chỉ số 0.

11
Chờ đã, điều đó có nghĩa là tại thời điểm viết bài, bạn 33 hay 34 tuổi?
Alec Jacobson

8
33, đó là năm thứ 34 của mình
Jason S

14

Một danh sách khá lớn các ngôn ngữ có trên Wikipedia trong mục So sánh các ngôn ngữ lập trình (mảng) trong bảng "Danh sách tham chiếu chéo hệ thống mảng" (Cột chỉ mục cơ sở mặc định)

Điều này có một cuộc thảo luận tốt về 1- so với 0- được lập chỉ mục và đăng ký nói chung

Trích dẫn từ blog:

EWD831 của EW Dijkstra, 1982.

Khi xử lý một chuỗi có độ dài N, các phần tử mà chúng ta muốn phân biệt bằng chỉ số con, câu hỏi gây khó chịu tiếp theo là giá trị chỉ số dưới nào cần gán cho phần tử bắt đầu của nó. Tuân theo quy ước a) cho kết quả, khi bắt đầu với chỉ số con 1, phạm vi chỉ số con 1 ≤ i <N + 1; bắt đầu bằng 0, tuy nhiên, cho phạm vi đẹp hơn 0 ≤ i <N. Vì vậy, chúng ta hãy để thứ tự của chúng ta bắt đầu từ 0: thứ tự (chỉ số con) của một phần tử bằng số phần tử đứng trước nó trong dãy. Và luân lý của câu chuyện là chúng ta đã coi trọng hơn - sau ngần ấy thế kỷ! - số 0 như một số tự nhiên nhất.

Nhận xét :: Nhiều ngôn ngữ lập trình đã được thiết kế mà không chú ý đến chi tiết này. Trong FORTRAN, các đăng ký luôn bắt đầu từ 1; trong ALGOL 60 và PASCAL, quy ước c) đã được thông qua; SASL gần đây hơn đã dựa trên quy ước FORTRAN: một chuỗi trong SASL đồng thời là một hàm trên các số nguyên dương. Điều đáng tiếc! (Phần cuối của chú thích.)


4
Rất nhiều kỹ sư không phải cs sẽ (và làm) không đồng ý với một số quan điểm của Dijkstra, liên quan đến rằng trong toán học xa-bàn phím 1 vẫn là phần tử đầu tiên "mặc định" của một mảng.
Rook 30/09/09

Ngoài ra, trong fortran, chỉ số con của mảng không phải lúc nào cũng bắt đầu từ 1
Rook 30/09/09

11
Dĩ nhiên Dijkstra đang trình bày một quan điểm rất thiên vị. Hãy xem xét rằng hầu hết mọi người sẽ mô tả phạm vi của các mảng dựa trên 1 là "1 ≤ i ≤ N", điều này đẹp hơn rất nhiều so với "0 ≤ i ≤ N-1".
RBarryYoung

Vâng, quan điểm của Dijkstra là rất thiên vị, và bên cạnh đó, giả định về một mô hình khác với cách mọi người viết mã ngày nay - ngày nay, có rất ít lập luận chống lại việc lập chỉ mục dựa trên 1 so với trước đây, ngay cả khi chỉ vì for-in.
Llamageddon

11

Fortran, Matlab, Pascal, Algol, Smalltalk và nhiều người khác.


4
Mảng Pascal có thể bắt đầu bất cứ lúc nào chỉ số, không nhất thiết phải là 0 hoặc 1
Paul R

11

Bạn có thể làm điều đó trong Perl

$[ = 1;  # set the base array index to 1

Bạn cũng có thể bắt đầu với 42 nếu bạn cảm thấy như vậy. Điều này cũng ảnh hưởng đến các chỉ mục chuỗi.

Trên thực tế, sử dụng tính năng này rất không được khuyến khích.


11

Ngoài ra trong Ada, bạn có thể xác định các chỉ số mảng của mình theo yêu cầu:

A : array(-5..5) of Integer;       -- defines an array with 11 elements
B : array(-1..1, -1..1) of Float;  -- defines a 3x3 matrix

Ai đó có thể tranh luận rằng phạm vi chỉ số mảng do người dùng xác định sẽ dẫn đến các vấn đề bảo trì. Tuy nhiên, việc viết mã Ada theo cách không phụ thuộc vào chỉ số mảng là điều bình thường. Với mục đích này, ngôn ngữ cung cấp các thuộc tính phần tử, các thuộc tính này được tự động xác định cho tất cả các loại đã xác định:

A'first   -- this has the value -5
A'last    -- this has the value +5
A'range   -- returns the range -5..+5 which can be used e.g. in for loops

7

JDBC (không phải là một ngôn ngữ mà là một API)

String x = resultSet.getString(1);  // the first column

7
+1 Đó là sự điên rồ hoàn toàn, nó luôn khiến tôi phải hứng chịu, do thực tế là mọi thứ khác trong Java đều là 0!
Adrian Smith

2
Đó có thể là bởi vì SQL cũng sử dụng 1 chỉ số dựa trên ví dụ ORDER BY 1(cột đầu tiên) hoặc SUBSTRING(name, 2)(bắt đầu từ nhân vật thứ 2)
Alex Jasmin

Lưu ý rằng Hibernate, một ORM phổ biến cho Java (thường) nằm trên JDBC có các phương thức setString trong đó chỉ mục dựa trên 0. Gây nhầm lẫn.
Thilo


5

Lua - đáng thất vọng


2
Có gì sai với lua có chỉ mục dựa trên 1? tôi làm cho nó thân thiện hơn cho người mới bắt đầu lập trình.
RCIX

4

Đã tìm thấy một - Lua (ngôn ngữ lập trình)

Kiểm tra phần Mảng cho biết -

"Mảng Lua dựa trên 1: chỉ mục đầu tiên là 1 chứ không phải 0 như đối với nhiều ngôn ngữ lập trình khác (mặc dù chỉ số rõ ràng là 0 được cho phép)"


4

VB Classic, ít nhất là thông qua

Option Base 1

Cơ sở 1? Xin vui lòng không, unary là sooo trở nên cồng kềnh ...

VB.NET cũng - ngôn ngữ duy nhất mà Dim x(10)tạo ra 11 yếu tố ...
Josh Lee

@jleedev: Không chính xác - VB.NET-Mảng được 0dựa trên cơ sở và số khai báo giới hạn trên (các chỉ số hợp lệ nằm trong khoảng từ 0đến 10). Điều này rất phù hợp vì các vòng lặp For của VB là bao gồm .
Dario

4

Các chuỗi trong Delphi bắt đầu từ 1.

(Mảng tĩnh phải có giới hạn dưới được chỉ định rõ ràng. Mảng động luôn bắt đầu từ 0)



3

Ada và Pascal.


Tôi không nghĩ Pascal nên được đưa vào vì nó sử dụng cả 0 và 1 tùy thuộc vào những gì đang được xem xét. Chuỗi là 1, nhưng mảng là 0.
Tom A

1
Đã lâu rồi, nhưng tôi tin rằng bạn có thể sử dụng bất kỳ chỉ mục nào bạn thích làm đầu / cuối của một mảng trong Pascal, kể cả các giá trị âm. ARRAY [-5 ..- 2] sẽ tạo một mảng gồm 4 phần tử.
Dan Dyer

3

PL / SQL . Kết quả của điều này là khi sử dụng các ngôn ngữ bắt đầu từ 0 và tương tác với Oracle, bạn cần tự xử lý các chuyển đổi 0-1 để truy cập mảng theo chỉ mục. Trong thực tế, nếu bạn sử dụng một cấu trúc như foreachtrên các hàng hoặc truy cập các cột theo tên, thì đó không phải là vấn đề lớn, nhưng bạn có thể muốn cột ngoài cùng bên trái, ví dụ, sẽ là cột 1.



3

Toàn bộ dòng ngôn ngữ Wirthian bao gồm Pascal, Object Pascal, Modula-2, Modula-3, Oberon, Oberon-2 và Ada (cộng với một số ngôn ngữ khác mà tôi có thể đã bỏ qua) cho phép các mảng được lập chỉ mục từ bất kỳ điểm nào bạn thích bao gồm, rõ ràng, 1.

Erlang lập chỉ mục các bộ và mảng từ 1.

Tôi nghĩ - nhưng không còn tích cực nữa - rằng Algol và PL / 1 đều chỉ số từ 1. Tôi cũng khá chắc chắn rằng Cobol chỉ số từ 1.

Về cơ bản, hầu hết các ngôn ngữ lập trình cấp cao trước C được lập chỉ mục từ 1 (với các ngôn ngữ hợp ngữ là một ngoại lệ đáng chú ý vì những lý do hiển nhiên - và lý do C lập chỉ mục từ 0) và nhiều ngôn ngữ từ bên ngoài bá chủ của C vẫn làm như vậy cho đến ngày nay.



2

Visual FoxPro, FoxPro và Clipper đều sử dụng các mảng trong đó phần tử 1 là phần tử đầu tiên của một mảng ... Tôi cho rằng đó là ý của bạn khi được lập chỉ mục 1.


2

Tôi thấy rằng kiến ​​thức về fortran ở đây vẫn còn trên phiên bản '66.

Fortran có biến cả giới hạn dưới và giới hạn trên của một mảng.

Có nghĩa là, nếu bạn khai báo một mảng như:

real, dimension (90) :: x

thì 1 sẽ là giới hạn dưới (theo mặc định).

Nếu bạn tuyên bố nó như thế nào

real, dimension(0,89) :: x

tuy nhiên, nó sẽ có giới hạn dưới là 0.

Mặt khác, nếu bạn tuyên bố nó như

real, allocatable :: x(:,:)

thì bạn có thể phân bổ nó cho bất cứ thứ gì bạn thích. Ví dụ

allocate(x(0:np,0:np))

có nghĩa là mảng sẽ có các phần tử

x(0, 0), x(0, 1), x(0, 2 .... np)
x(1, 0), x(1, 1), ...
.
.
.
x(np, 0) ...

Ngoài ra còn có một số kết hợp thú vị hơn có thể:

real, dimension(:, :, 0:) :: d
real, dimension(9, 0:99, -99:99) :: iii

được để lại làm bài tập về nhà cho người đọc quan tâm :)

Đây chỉ là những thứ tôi nhớ ra khỏi đầu. Vì một trong những điểm mạnh chính của fortran là khả năng xử lý mảng, rõ ràng là có rất nhiều điểm mạnh khác không được đề cập ở đây.


VB dựa trên 0 theo mặc định (có từ BASIC đầu tiên).
Pavel Minaev 30/09/09

@Pavel Minaev - sai lầm của tôi. Đã chỉnh lý.
Rook 30/09/09


2

Mathematica và Maxima, bên cạnh các ngôn ngữ khác đã được đề cập.


2

Informix, bên cạnh các ngôn ngữ khác đã được đề cập.


2

Cơ bản - không chỉ VB, mà tất cả các phiên bản đánh số dòng cũ của những năm 1980.

Richard





0

Mặc dù C theo thiết kế 0 được lập chỉ mục, có thể sắp xếp để một mảng trong C được truy cập như thể nó được lập chỉ mục 1 (hoặc bất kỳ giá trị nào khác). Không phải là điều bạn mong đợi một C coder bình thường làm thường xuyên, nhưng nó đôi khi có ích.

Thí dụ:

#include <stdio.h>
int main(){
    int zero_based[10];
    int* one_based;
    int i;
    one_based=zero_based-1;

    for (i=1;i<=10;i++) one_based[i]=i;
    for(i=10;i>=1;i--) printf("one_based[%d] = %d\n", i, one_based[i]);
    return 0;
}

5
Điểm mấu nơi bạn trừ đi 1từ zero_basedlà hành vi không xác định theo tiêu chuẩn ISO C - đó là không hợp pháp để chuyển con trỏ đến trước phần tử đầu tiên trong một mảng. Ví dụ: một triển khai tuân thủ có thể chèn các kiểm tra vượt quá giới hạn sẽ được kích hoạt bởi mã của bạn.
Pavel Minaev 30/09/09

Đúng. Tôi chỉ đăng bài này như một sự tò mò thú vị hơn là một kỹ thuật lập trình nghiêm túc. Trong gcc, không có gì xấu xảy ra miễn là một trong những giới hạn của mảng ban đầu.
MAK
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.