Eine hier gestellte Frage erinnerte mich an eine Diskussion mit einem anderen Programmierer. Er argumentierte, dass nullbasierte Arrays durch einsbasierte Arrays ersetzt werden sollten, da nullbasierte Arrays ein Implementierungsdetail sind, das von der Art und Weise herrührt, wie Arrays und Zeiger sowie Computerhardware funktionieren Sprachen.
Jetzt kann ich nicht wirklich gut debattieren, daher kann ich keine guten Gründe nennen, bei nullbasierten Arrays zu bleiben, die sich nicht angemessener anfühlen. Warum ist Null der gemeinsame Ausgangspunkt für Arrays?
Antworten:
Ich denke, keiner von uns kann ein stärkeres Argument liefern als der Artikel von Edsger W. Dijkstra "Warum die Nummerierung bei Null beginnen sollte" .
quelle
Berechtigungsargument
Nun ... Anscheinend basieren die meisten Sprachen, einschließlich der jüngsten, auf Null. Da diese Sprachen von sehr erfahrenen Leuten geschrieben wurden, muss sich Ihr Freund geirrt haben ...
Warum eins?
Warum wäre 1 ein besserer Startindex als Null? Warum nicht 2 oder 10? Die Antwort selbst ist interessant, weil sie viel über den Durchdringungsprozess der Leute zeigt, die die Idee verteidigen.
Das erste Argument ist , dass es natürlich ist, weil der erste in der Regel das ist eine vor allen anderen, zumindest für die Mehrheit der Menschen ...
Das Zahlen- ein Argument ist , dass der letzte Index ist auch die Größe des Arrays ...
Ich bin immer noch beeindruckt von der "Qualität" der Gründe, die ich normalerweise für diese Art von Argumenten höre ... und noch mehr, wenn ich daran erinnert werde, dass ...
Warum nicht Null?
... "Eins-basierte" Notationen sind Überbleibsel der westlichen Kultur, die die Existenz von Null jahrhundertelang ignorierten, wenn nicht sogar mehr.
Ob Sie es glauben oder nicht, der ursprüngliche gregorianische Kalender geht von -3, -2, -1, 1, 2, 3 ... Versuchen Sie sich das Problem vorzustellen, das es für die westliche Wissenschaft mit sich brachte (zum Beispiel wie viele Jahre vom 1. Januar bis zum 2. Januar) bis zum 1. Januar 2, um zu sehen, dass der ursprüngliche gregorianische Kalender mit etwas so Einfachem wie Subtraktion in Konflikt steht ...).
Das Festhalten an einbasierten Arrays ist wie (nun, ich werde dafür herabgestuft ... ^ _ ^ ...), das Festhalten an Meilen und Yards im 21. Jahrhundert ...
Warum Null? Weil es Mathe ist!
Zuerst(Ups ... Entschuldigung ... ich werde es noch einmal versuchen)Null , Null ist nichts, man ist etwas. In einigen religiösen Texten heißt es: "Am Anfang war nichts". Einige Computerdiskussionen können so brennend sein wie religiöse Debatten, daher ist dieser Punkt nicht so thematisch, wie es scheint ... ^ _ ^
Erstens ist es einfacher, mit einem nullbasierten Array zu arbeiten und dessen nullten Wert zu ignorieren, als mit einem einbasierten Array zu arbeiten und den nullten Wert zu finden. Dieser Grund war fast so dumm wie der vorherige, aber das ursprüngliche Argument für einseitige Arrays war auch ein ziemlicher Trugschluss.
Zweitens : Wenn Sie mit Zahlen arbeiten, stehen die Chancen gut, dass Sie sich mit Mathematik befassen, und wenn Sie sich mit Mathematik befassen, stehen die Chancen gut, dass Sie nicht in der Stimmung sind, veraltete Konventionen zu umgehen. Die einseitige Notation plagte Mathe und Datumsangaben über Jahrhunderte hinweg, und indem wir aus unseren Fehlern lernen, sollten wir uns bemühen, dies in zukunftsorientierten Wissenschaften (einschließlich Computersprachen) zu vermeiden.
Drittens : Weisen Sie Computersprachen-Arrays, die an Hardware gebunden sind, ein C-Array mit 21 Ganzzahlen zu, und bewegen Sie den Zeiger 10 nach rechts, um ein natürliches [-10 bis 10] -Array zu erhalten. Dies ist für Hardware nicht selbstverständlich. Aber es ist für Mathe. Natürlich könnte Mathematik überholt sein, aber als ich das letzte Mal nachgesehen habe, glaubten die meisten Menschen auf der Welt, dass dies nicht der Fall ist.
Viertens : Wie bereits an anderer Stelle erwähnt, wäre der erste Index auch für diskrete Positionen (oder auf diskrete Werte reduzierte Entfernungen) Null, wie der Fußboden in einem Gebäude (beginnend bei Null), der abnehmende Countdown (3, 2, 1, NULL) !), die Bodenhöhe, das erste Pixel eines Bildes, die Temperatur (null Kelvin, für den absoluten Nullpunkt oder null Grad Celsius, als Wassergefriertemperatur von 273 K). In der Tat ist das einzige, was wirklich mit einem beginnt, die traditionelle Art des " Ersten , Zweiten , Dritten usw." Iterationsnotation , die mich natürlich zum nächsten Punkt führt ...
Fünf der nächste Punkt (die natürlicherweise das folgende vorherigen ) ist , dass High-Level - Container zugegriffen werden soll, nicht durch den Index, sondern von Iteratoren , es sei denn , die Indizes selbst einen intrinsischen Wert haben. Ich bin überrascht, dass Ihr Verfechter der "höheren Sprache" das nicht erwähnt hat. In dem Fall, dass der Index selbst wichtig ist, können Sie wetten, dass Sie die Hälfte der Zeit eine mathematische Frage haben. Sie möchten also, dass Ihr Container mathematikfreundlich und nicht mathematisch deaktiviert ist, wie z. B. "Ihr alter Gregorianischer Kalender", der bei 1 beginnt, und dass er wiederauferlegte Hacks benötigt, damit er funktioniert.
Fazit
Das Argument Ihres Programmierkollegen ist ein Irrtum, weil es die gesprochenen / geschriebenen Sprachgewohnheiten, die von Natur aus verschwommen sind, unnötig mit Computersprachen verknüpft (bei denen Sie nicht möchten, dass Ihre Anweisungen verwischt werden) und weil eine Hardware falsch zugeordnet wird Aus diesem Grund hofft er, Sie zu überzeugen, dass das nullbasierte Array der Vergangenheit angehört, da die Sprachen in der Abstraktion immer höher werden.
Nullbasierte Arrays sind aus mathematischen Gründen nullbasiert. Nicht aus Hardware-Gründen.
Wenn dies ein Problem für Ihren Programmierkollegen ist, lassen Sie ihn mit echten Konstrukten auf hoher Ebene wie Iteratoren und foreach-Schleifen programmieren.
quelle
Halboffene Intervalle komponieren gut. Wenn Sie es
0 <= i < lim
mitn
Elementen zu tun haben und diese erweitern möchten , haben die neuen Elemente Indizes im Bereichlim <= i < lim + n
. Das Arbeiten mit nullbasierten Arrays erleichtert das Rechnen beim Teilen oder Verketten von Arrays oder beim Zählen von Elementen . Man hofft, dass die einfachere Arithmetik zu weniger Zaunpfostenfehlern führt .quelle
Bestimmte Arten der Array-Manipulation werden bei 1-basierten Arrays verrückt kompliziert, bleiben jedoch bei 0-basierten Arrays einfacher.
An einem Punkt habe ich einige numerische Analyseprogramme erstellt. Ich habe mit Algorithmen gearbeitet, um komprimierte, spärliche Matrizen zu manipulieren, die sowohl in FORTRAN als auch in C ++ geschrieben wurden.
Die FORTRAN-Algorithmen hatten viel
a[i + j + k - 2]
, während die C ++ hattena[i + j + k]
, weil das FORTRAN-Array 1-basiert war, während das C ++ - Array 0-basiert war.quelle
Der Index in einem Array ist eigentlich kein Index. Es ist einfach ein Versatz, der der Abstand vom Anfang des Arrays ist. Das erste Element befindet sich am Anfang des Arrays, sodass kein Abstand besteht. Daher ist der Offset 0.
quelle
Die Gründe sind nicht nur historisch: C und C ++ sind immer noch verbreitet und Zeigerarithmetik ist ein sehr gültiger Grund dafür, dass Arrays bei Index 0 beginnen.
Für andere Sprachen ohne Zeigerarithmetik ist es eher eine Konvention als etwas anderes, ob sich das erste Element am Index 0 oder 1 befindet.
Das Problem ist, dass Sprachen, die Index 1 als erstes Element verwenden, nicht im luftleeren Raum existieren und normalerweise mit Bibliotheken interagieren müssen, die oft in C oder C ++ geschrieben wurden.
VB und seine abgeleiteten Aromen haben darunter gelitten, dass Arrays entweder bei 0 oder 1 beginnen, und dies war lange Zeit eine Quelle von Problemen.
Fazit ist: Es spielt keine Rolle, in welcher Sprache der erste Elementindex angezeigt wird, solange er durchgehend konsistent ist. Das Problem ist, dass es in der Praxis schwieriger ist, mit 1 als erstem Index zu arbeiten.
quelle
And
undOr
bitweise zu sein hat nichts mit VB6 zu tun, ist dies die einzige logische Lösung für eine Sprache vom Typ VB. Sie tun habenAndAlso
undOrElse
für Ihre logischen Operationen.And
undOr
bitweise zu sein hat alles mit VB6 zu tun, weil sie bitweise in VB6 waren. Die hässlichen OperatorenAndAlso
undOrElse
sollten bitweise erfolgen, da bitweise Operationen weitaus seltener sind als logische. Es gibt viele hässliche Warzen wie diese, die aufgrund der "Abwärtskompatibilität" in der Sprache verbleiben, wie die Tatsache, dass ByVal überall verputzt ist, obwohl es die Standardeinstellung ist.Nullbasierte Arrays haben ihre Wurzeln in C und sogar in Assembler. Mit C funktioniert die Zeigermathematik im Grunde so:
Zur Veranschaulichung sei angenommen, dass
int a[4]
bei 0xFF00 die Adressen sind:Mit nullbasierten Indizes ist die Adressberechnung also einfach:
Adresse des Elements = Adresse des Arrays + Index * Größe von (Typ)
Tatsächlich sind die Ausdrücke in C alle gleich:
Bei einbasierten Arrays ist die Mathematik (noch dazu) etwas komplizierter.
Die Gründe sind also weitgehend historisch.
quelle
Wenn Sie nullbasierte Arrays verwenden, entspricht die Länge des Arrays der Menge der gültigen Indizes. Zumindest sagt das die Peano-Arithmetik:
In gewissem Sinne ist es die natürlichste Notation.
quelle
Weil es in C eine starke Korrelation zwischen Arrays und Zeigern gibt
* p ist dasselbe wie * (p + 0)
mit einem Anfangsindex von 1 bekommen Sie später Kopfschmerzen
quelle
Ein Heap ist ein Beispiel für die Vorteile von 1-basierten Arrays. Wenn ein Index i gegeben ist , ist der Index des Elternteils und des linken Kindes von i
PARENT
[ i ] = i ≤ 2LCHILD
[ i ] = i × 2Aber nur für 1-basierte Arrays. Für 0-basierte Arrays haben Sie
PARENT
[ i ] = ( i + 1) ≤ 2 - 1LCHILD
[ I ] = ( i + 1) × 2 - 1Und dann haben Sie die Eigenschaft, dass i auch die Größe des Subarrays zu diesem Index ist (dh Indizes im Bereich [1, i ]).
Aber am Ende spielt es keine Rolle, denn Sie können ein 0-basiertes Array in ein 1-basiertes Array umwandeln, indem Sie ein Element mehr als normal zuweisen und die Null ignorieren. Auf diese Weise können Sie die Vorteile von 1-basierten Arrays bei Bedarf aktivieren und die 0-basierten Arrays für eine sauberere Arithmetik in fast allen anderen Situationen beibehalten.
quelle
Mein Gefühl ist, dass es völlig willkürlich ist. An null- oder einbasierten Arrays ist nichts Besonderes. Seit ich mich von Visual Basic befreit habe (meistens mache ich kleine Dinge in Excel), habe ich nicht mehr mit 1-basierten Arrays gearbeitet, und ... es ist dasselbe. Tatsache ist, dass, wenn Sie das dritte Element des Arrays benötigen, es nur ein Implementierungsdetail ist, das als 3 oder 2 bezeichnet wird. 99% Ihrer Arbeit mit Arrays sind jedoch nur an zwei absoluten Punkten interessiert: dem ersten Element und die Zählung oder Länge. Auch hier handelt es sich nur um ein Implementierungsdetail, bei dem das erste Element null statt eins heißt oder das letzte Element count-1 oder stattdessen count heißt.
Bearbeiten: Einige der Antwortenden haben erwähnt, dass 1-basierte Arrays anfälliger für Fencepost-Fehler sind. Nach meiner Erfahrung, wenn ich jetzt darüber nachdenke, ist dies wahr. Ich erinnere mich, dass ich in VB gedacht habe: "Das wird entweder funktionieren oder explodieren, weil ich um eins abwesend bin." In Java passiert das nie. Obwohl ich dachte, dass ich besser werde, weisen einige der Antwortenden auf Fälle hin, in denen 0-basierte Arrays zu einer besseren Arithmetik führen, AUCH, wenn Sie sich nicht mit einer niedrigeren Sprache auseinandersetzen müssen.
quelle
Als C / C ++ - Programmierer von über 10 Jahren mit sehr guten Kenntnissen in Pascal und Delphi vermisse ich immer noch Pascals starke Überprüfung von Array-Grenzen und Indextypen sowie die damit verbundene Flexibilität und Sicherheit. Ein offensichtliches Beispiel hierfür sind Array-Daten, die Werte für jeden Monat enthalten.
Pascal:
Das Schreiben von ähnlichem Code in C-Sprachen ohne Verwendung von +/- 1 oder 'magischen Zahlen' ist eine ziemliche Herausforderung. Beachten Sie, dass Ausdrücke wie Days [2] und Days [Jan + Dec] einfach nicht kompiliert werden können, was für Leute, die noch in C oder Assembler denken, brutal erscheinen kann.
Ich muss sagen, dass es viele Aspekte von Pascal / Delphi-Sprachen gibt, die mir nicht entgehen, aber Arrays auf C-Null-Basis scheinen im Vergleich einfach "dumm" zu sein.
quelle
Der Grund, warum es bei 0 und nicht bei 1 beginnt, ist, dass Sie sich den Versatz so vorstellen können, wie weit vom Anfang des Speichers des Arrays dieses Element entfernt ist. Es heißt nicht, gib mir das 0. Element - es heißt, gib mir das Element, das von Anfang an 0 Elemente ist.
Eine andere Sichtweise ist, dass diese (zum größten Teil) gleichwertig sind:
Der Grund, warum der Standard niemals geändert wird, ist, dass C seit ungefähr 40 Jahren existiert. Es gibt keinen zwingenden Grund, dies zu ändern, und wenn dies der Fall wäre, würde der gesamte vorhandene Code, der davon abhängt, dass der Anfang des Arrays 0 ist, beschädigt.
quelle
array[n]
wien[array]
in C umschreiben . Es ist keine gute Idee, es zu tun, es ist verwirrend! Aber es ist legal (na ja, zumindest bis C89), weil diese Identität oben und die Tatsache, dass Addition kommutativ ist.Code, der einige Informationen zur ursprünglichen Position / relativen Position enthält, ist viel sauberer, wenn Arrays bei 0 beginnen.
Zum Beispiel: Der Code zum Kopieren eines Vektors an einer definierten Position in einem größeren Vektor ist ein Schmerz mit Arrays, die bei 1 beginnen:
Durch Opposition mit Arrays ab 0:
Wenn Sie anfangen, große Windungsformeln zu schreiben, ist dies ein Muss.
quelle
Warum nicht 2 oder 3 oder 20? Es ist nicht so, als ob 1-basierte Arrays einfacher oder einfacher zu verstehen wären als null-basierte Arrays. Um zu 1-basierten Arrays zu wechseln, müsste jeder Programmierer lernen, wie er mit Arrays arbeitet.
Wenn Sie mit Offsets in vorhandenen Arrays arbeiten, ist dies auch sinnvoller. Wenn Sie 115 Bytes aus einem Array gelesen haben, wissen Sie, dass der nächste Block bei 115 beginnt. Und so weiter, das nächste Byte ist immer die Größe der Bytes, die Sie gelesen haben. Bei 1-based müssten Sie immer eine hinzufügen.
Und manchmal müssen Sie mit Datenblöcken in Arrays umgehen, auch in einer Sprache ohne "echte" Zeigerarithmetik. In Java können sich Daten in Speicherzuordnungsdateien oder Puffern befinden. In diesem Fall wissen Sie, dass Block i die Größe * i hat. Bei einem 1-basierten Index wäre dies der Block * i + 1.
Bei einer 1-basierten Indizierung würden viele Techniken überall +1 erfordern.
quelle
Transformieren Sie mit 1-basierten Arrays ein eindimensionales Array in ein mehrdimensionales Array:
Beachten Sie, dass Ihre y- und z-Indizes 0-basiert sind (y - 1, z - 1), auch wenn Ihr Array 1-basiert ist. Unter bestimmten Umständen können Sie 0-basierte Indizes nicht vermeiden. Verwenden Sie aus Gründen der Konsistenz nicht immer 0-basierte Indizes.
quelle
Warum sollen Arrays um eins beginnen?
Wenn Sie sagen
a[x][y]
, übersetzt der Compiler dies in:a+(x*num_cols+y)
. Wenn Arrays um eins gestartet würden, würde dies werdena+(x*num_cols+y-1)
. Dies wäre jedes Mal eine zusätzliche Rechenoperation, wenn Sie auf ein Array-Element zugreifen möchten. Warum sollten Sie Programme verlangsamen wollen?quelle
Ich werde hier auf ein Glied treten und etwas anderes vorschlagen als ein ganzzahliges 'keyed' Array.
Ich glaube, Ihr Kollege schafft es, eine Eins-zu-Eins-Abbildung eines 'Sets' in der physischen Welt zu erstellen, in der wir immer mit 1 beginnen wenn Sie 1 zu 1 zwischen Software und der physischen Welt abgebildet sind.
Mein Vorschlag
Verwenden Sie keine ganzzahligen Arrays für das, was Sie speichern, sondern eine andere Art von Wörterbuch oder Schlüsselwertpaar. Diese werden dem realen Leben besser zugeordnet, da Sie nicht an eine beliebige Ganzzahl gebunden sind. Dies hat seinen Platz und ich würde empfehlen, es so oft wie möglich zu verwenden, da die Mapping-Konzepte 1 zu 1 zwischen Software und der physischen Welt von Vorteil sind.
dh
kvp['Name Server'] = "ns1.example.com";
(Dies ist nur eines von Millionen möglichen Beispielen).Discaimer
Dies funktioniert definitiv nicht, wenn Sie mit Konzepten arbeiten, die auf Mathematik basieren, da Mathematik der tatsächlichen Implementierung eines Computers näher ist. Die Verwendung von kvp-Sets wird hier nichts nützen, aber tatsächlich die Dinge durcheinander bringen und es problematischer machen. Ich habe nicht alle Eckfälle durchdacht, in denen etwas besser als kvp oder als Array funktionieren könnte.
Die Endidee ist, nullbasierte Arrays oder Schlüsselwertpaare zu verwenden, wenn es sinnvoll ist. Denken Sie daran, dass jedes Problem wie ein Nagel aussieht, wenn Sie nur einen Hammer haben.
quelle
Persönlich ist das eine Argument, wenn Array-Indizes als Offsets betrachtet werden. Es macht einfach Sinn.
Man könnte sagen, dass es das erste Element ist, aber der Versatz des ersten Elements relativ zum Ursprung des Arrays ist Null. Wenn Sie also den Array-Ursprung nehmen und Null addieren, erhalten Sie das erste Element.
Bei der Berechnung ist es also einfacher, Nullen hinzuzufügen, um das erste Element zu finden, als eine hinzuzufügen und dann eine zu entfernen.
Ich denke, jeder, der ein paar Sachen auf niedrigerem Level gemacht hat, denkt immer den Null-Weg. Und die Leute, die anfangen oder an höhere Level gewöhnt sind, wünschen sich oft nicht-algorithmische Programmierung für ein Basis-Ein-System. Oder vielleicht sind wir nur durch vergangene Erfahrungen voreingenommen.
quelle
Die beiden einzigen (sehr) schwerwiegenden Gründe für die Verwendung von 0-basierten Indizes anstelle von 1-basierten Indizes scheinen zu vermeiden, dass viele Programmierer UND aus Gründen der Abwärtskompatibilität neu ausgebildet werden .
In allen Antworten, die Sie erhalten haben, habe ich keine weiteren ernsthaften Argumente gegen 1-basierte Indizes gesehen.
Tatsächlich basieren Indizes von Natur aus auf 1 , und hier ist der Grund dafür.
Zuerst müssen wir fragen: Woher kommen Arrays? Haben sie reale Entsprechungen? Die Antwort lautet: Ja, so modellieren wir Vektoren und Matrizen in der Informatik. Vektoren und Matrizen sind jedoch mathematische Konzepte, die vor dem Computerzeitalter auf 1 basierende Indizes verwendeten (und die heutzutage immer noch meistens auf 1 basierende Indizes verwenden).
In der realen Welt sind Indizes 1-Basen.
Wie Thomas oben sagte, verwenden Sprachen, die Indizes mit 0 Basen verwendeten, tatsächlich Offsets , keine Indizes. Entwickler, die diese Sprachen verwenden, denken an Offsets und nicht an Indizes. Dies wäre kein Problem, wenn die Dinge klar formuliert wären, aber das sind sie nicht. Viele Entwickler, die Offsets verwenden, sprechen immer noch über Indizes. Und viele Entwickler, die Indizes verwenden, wissen immer noch nicht, dass C, C ++, C #, ... Offsets verwenden.
Dies ist ein Wortlautproblem .
(Anmerkung zu Diskstras Artikel - Er sagt genau das, was ich oben gesagt habe : Mathematiker verwenden 1-basierte Indizes . Diskstra ist jedoch der Meinung, dass Mathematiker sie nicht verwenden sollten, da ein Ausdruck dann hässlich wäre (z. B .: 1 <= n <= 0) Nun, ich bin mir nicht sicher, ob er damit Recht hat. Einen solchen Paradigmenwechsel durchzuführen, um diese außergewöhnlichen leeren Sequenzen zu vermeiden, scheint eine Menge Ärger für ein kleines Ergebnis zu sein.
quelle
Haben Sie sich jemals über das "20. Jahrhundert" geärgert, das sich auf die 1900er Jahre bezieht? Nun, es ist eine gute Analogie für die mühsamen Dinge, mit denen Sie sich bei der Verwendung von 1-basierten Arrays ständig befassen.
Betrachten Sie eine allgemeine Array-Aufgabe wie die Lesemethode .net IO.stream:
Ich schlage vor, dass Sie Folgendes tun, um sich davon zu überzeugen, dass 0-basierte Arrays besser sind:
Schreiben Sie in jeden Indexierungsstil eine BufferedStream- Klasse, die das Lesen unterstützt. Sie können die Definition der Lesefunktion für die 1-basierten Arrays ändern (z. B. eine Untergrenze anstelle eines Offsets verwenden). Sie brauchen nichts Besonderes, machen Sie es einfach.
Welche dieser Implementierungen ist einfacher? Welche hat hier und da +1 und -1 Offsets gestreut? Das ist was ich dachte. Tatsächlich würde ich argumentieren, dass der einzige Fall, in dem der Indexierungsstil keine Rolle spielt, darin besteht, dass Sie etwas hätten verwenden sollen, das kein Array ist, wie z. B. ein Set.
quelle
Das liegt daran, wie Arrays aufgebaut sind. Es macht wenig Sinn, von einem zu beginnen. Ein Array ist eine Basisadresse im Speicher, eine Größe und ein Index. Um auf das n-te Element zuzugreifen, ist es:
0 ist also offensichtlich der erste Versatz.
quelle
Es gibt tatsächlich verschiedene Möglichkeiten, dies zu implementieren:
Letztendlich denke ich nicht, dass es wichtig ist, ob eine Sprache 0 oder 1 basierte Arrays verwendet. Ich denke jedoch, dass die beste Wahl die Verwendung von 0-basierten Arrays ist, da die meisten Programmierer an diese Konvention gewöhnt sind und sie mit der überwiegenden Mehrheit des bereits geschriebenen Codes übereinstimmt.
Der einzige Weg, um wirklich etwas falsch zu machen, besteht darin, inkonsistent zu sein wie Visual Basic. Die Codebasis, die ich zurzeit verwalte, ist in 0- und 1-basierte Arrays aufgeteilt. und es ist außerordentlich schwierig herauszufinden, welches welches ist. Dies führt zu einer nervig ausführlichen for-Schleife:
quelle
Null ist natürlich, wenn über die Position eines Elements in einer linearen Sammlung gesprochen wird.
Stellen Sie sich ein Regal voller Bücher vor - das erste Buch befindet sich bündig mit der Seitenwand des Regals - das ist die Position Null.
Ich denke, es hängt davon ab, ob Sie Array-Indizes als Mittel zum Finden von Dingen oder zum Verweisen auf Dinge betrachten.
quelle
Ich bevorzuge einen auf 0 basierenden Index, da modulo (und der AND-Operator, wenn er für modulo verwendet wird) für einige Werte immer 0 zurückgibt.
Ich finde mich oft mit Arrays wie folgt:
Ich verstehe diese Art von Code oft falsch, wenn ich 1-basierte Indizes verwende.
quelle
Es ist schwierig, 0-Base zu verteidigen, ohne viel Array-basierten Code zu programmieren, wie z. B. die Suche nach Zeichenfolgen und verschiedene Sortier- / Zusammenführungsalgorithmen, oder mehrdimensionale Arrays in einem eindimensionalen Array zu simulieren. Fortran ist 1-basiert, und Sie brauchen viel Kaffee, um diese Art von Code richtig zu machen.
Aber es geht weit darüber hinaus. Es ist eine sehr nützliche mentale Gewohnheit, über die Länge von etwas nachzudenken, anstatt über die Indizes seiner Elemente. Wenn Sie beispielsweise pixelbasierte Grafiken erstellen, ist es viel klarer, sich Koordinaten als zwischen Pixel fallend vorzustellen, als auf diesen. Auf diese Weise enthält ein 3x3-Rechteck 9 Pixel, nicht 16.
Ein etwas weit hergeholteres Beispiel ist die Idee der Vorausschau beim Parsen oder beim Drucken von Zwischensummen in einer Tabelle. Der "gesunder Menschenverstand" -Ansatz besagt, 1) das nächste Zeichen, Token oder die nächste Tabellenzeile zu erhalten und 2) zu entscheiden, was damit zu tun ist. Der Look-Ahead-Ansatz besagt: 1) Angenommen, Sie können es sehen und entscheiden, ob Sie es wollen, und 2) Wenn Sie es wollen, "akzeptieren" Sie es (wodurch Sie das nächste sehen können). Dann, wenn Sie den Pseudocode ausschreiben, ist es viel einfacher.
Ein weiteres Beispiel ist die Verwendung von "goto" in Sprachen, in denen Sie keine Wahl haben, z. B. in MS-DOS-Batchdateien. Der "gesunder Menschenverstand" -Ansatz besteht darin, zu erledigende Codeblöcke mit Etiketten zu versehen und als solche zu kennzeichnen. Oft ist es besser, Beschriftungen an den Enden von Codeblöcken anzubringen, um sie zu überspringen. Dies macht es "strukturiert" und viel einfacher zu ändern.
quelle
Es ist einfach so und das schon seit vielen Jahren. Es zu ändern oder sogar zu debattieren, ist ebenso sinnlos wie sich zu ändern oder über sich ändernde Ampeln zu debattieren. Machen wir Blau = Stopp, Rot = Los.
Informieren Sie sich über Änderungen, die im Laufe der Zeit in Numerical Recipes for C ++ vorgenommen wurden. Sie hatten Makros verwendet, um 1-basierte Indizierungen zu fälschen, aber in der Ausgabe von 2001 gaben sie auf und schlossen sich der Herde an. Möglicherweise gibt es auf der Website www.nr.com Aufschluss über die Gründe dafür
Übrigens nerven auch die Varianten, einen Bereich aus einem Array anzugeben. Beispiel: Python vs. IDL; a [100: 200] vs a [100: 199], um 100 Elemente zu erhalten. Ich muss nur die Macken jeder Sprache lernen. Eine Sprache zu ändern, die sich auf die eine oder andere Weise anpasst, würde ein solches Zähneknirschen verursachen und kein wirkliches Problem lösen.
quelle
Ich bevorzuge 0-basierte Arrays, da dies, wie von anderen erwähnt, die Mathematik erleichtert. Wenn wir zum Beispiel ein eindimensionales Array von 100 Elementen haben, die ein 10x10-Gitter emulieren, wie lautet dann der Array-Index i des Elements in Zeile r, Spalte c:
Und angesichts des Index i lautet die Rückkehr zur Zeile und Spalte:
Angesichts der Tatsache, dass die obigen Berechnungen bei der Verwendung von 1-basierten Arrays deutlich komplexer sind, erscheint es logisch, 0-basierte Arrays als Standard zu wählen.
Ich denke jedoch, dass jemand behaupten könnte, dass meine Logik fehlerhaft ist, da ich davon ausgehe, dass es einen Grund geben würde, 2D-Daten in einem 1D-Array darzustellen. Ich bin in C / C ++ auf eine Reihe solcher Situationen gestoßen, muss aber zugeben, dass das Ausführen solcher Berechnungen in gewisser Weise sprachabhängig ist. Wenn Arrays die gesamte Indexberechnung für den Client wirklich zu jeder Zeit durchgeführt haben, kann der Compiler Ihre M-basierten Array-Zugriffe zur Kompilierungszeit einfach in 0-basierte umwandeln und alle diese Implementierungsdetails vor dem Benutzer verbergen. Tatsächlich könnte jede Konstante zur Kompilierungszeit verwendet werden, um denselben Satz von Operationen auszuführen, obwohl solche Konstrukte wahrscheinlich nur zu unverständlichem Code führen würden.
Vielleicht wäre ein besseres Argument, dass die Minimierung der Anzahl der Arrayindexoperationen in einer Sprache mit 1-basierten Arrays die Ausführung einer Ganzzahldivision unter Verwendung der Ceiling-Funktion erfordern würde. Aus mathematischer Sicht sollte die Ganzzahldivision jedoch d Rest r zurückgeben, wobei d und r beide positiv sind. Daher sollten 0-basierte Arrays verwendet werden, um die Mathematik zu vereinfachen.
Wenn Sie beispielsweise eine Nachschlagetabelle mit N Elementen generieren, ist der nächste Index vor dem aktuellen Wert im Array für den Wert x (wobei Werte, bei denen das Ergebnis vor dem Runden eine Ganzzahl ist, ungefähr ignoriert werden):
Beachten Sie, dass bei Verwendung der Standardkonvention zum Abrunden von Arrays auf 1-Basis eine zusätzliche Operation erforderlich ist, die unerwünscht ist. Diese Art von Mathematik kann vom Compiler nicht ausgeblendet werden, da hier weniger Kenntnisse darüber erforderlich sind, was hinter den Kulissen passiert.
quelle
Ich wette, der Programmierer war nur verärgert über die Gegenintuitivität eines 0-basierten Arrays im täglichen Denken und plädierte für ein intuitiveres Mittel zur Beschreibung von Arrays. Ich finde es ironisch, dass wir als Menschen so viel Zeit damit verbracht haben, "Klassen" zu entwickeln, damit wir die Dinge in unserem Code menschlicher beschreiben können, aber wenn wir uns Arrays mit 0 gegen 1 ansehen, scheinen wir hängen zu bleiben die Logik davon allein.
In Bezug auf den Computer und mathematisch gesehen wird 0 wahrscheinlich besser sein, aber ich habe das Gefühl, dass hier ein Punkt übersehen wird. Wenn wir die Dinge menschlicher beschreiben wollten (z. B. Klassen), warum wollten wir das nicht auch für andere Teile der Sprache? Ist dies nicht gleichermaßen logisch oder gültig (oder hat diesbezüglich eine höhere Priorität ...), um eine Sprache für den Menschen leichter verständlich und benutzerfreundlicher zu machen und damit weniger anfällig für Szenarien, die dazu neigen, Logikfehler zu erzeugen und anfälliger zu sein? zur schnelleren Herstellung einer brauchbaren Kreation. PHP Beispiel:
gibt ein 1-basiertes Array pro Anfrage an.
Warum nicht die Norm haben:
Und die Ausnahme sein:
Im Falle von PHP ist mein Einsatz 80% der Zeit, in der ein 1-basiertes Array die Standardsyntax darstellt, um Logikfehler in realen Anwendungsfällen zu verringern oder zumindest im Durchschnitt nicht mehr zu verursachen, während es zu einer Menge wird Es ist für den Codierer einfacher, verwendbaren Code schneller zu erstellen. Denken Sie daran, ich gehe davon aus, dass es immer noch die Option Array (0 => 'value') gibt, wenn es benötigt wird, aber ich gehe auch davon aus, dass es die meiste Zeit praktisch ist, etwas zu haben, das näher an einer Beschreibung der realen Welt liegt.
Das klingt wirklich nicht allzu weit hergeholt von einer Anfrage, wenn man sie aus dieser Perspektive betrachtet. Wenn wir uns einer Schnittstelle nähern, sei es einem Betriebssystem oder einer Sprache für einen Programmierer, werden wir in den meisten Fällen umso glücklicher sein und weniger Missverständnisse zwischen Mensch und Computer (menschliche Logik). Bugs), und die schnellere Produktion, etc. werden wir haben. Wenn ich in der realen Welt 80% der Zeit Dinge mit 1 beschreibe, wenn ich Listen erstelle oder zähle, sollte der Computer meine Bedeutung idealerweise so interpretieren, dass er sie mit so wenig Informationen wie möglich versteht oder sich von meiner normalen Art, etwas zu beschreiben, unterscheidet. Kurz gesagt, je näher wir der realen Welt kommen, desto besser ist die Abstraktion. Was er also will, ist keineswegs dumm, da dies das ultimative Ziel ist und ein Beweis für das Bedürfnis nach mehr Abstraktion wäre. Der Computer kann es letztendlich immer noch als eine spezielle Verwendung eines 0-basierten Arrays ansehen. Es ist mir egal, wie der Computer es interpretiert, solange es für mich eine einfachere und intuitivere Möglichkeit ist, mit weniger Fehlern im Laufe der Zeit zu beschreiben, was ich will.
Das sind meine zwei Cent. Ich bezweifle ernsthaft, was er sagte oder was interpretiert wurde und was er meinte. Wahrscheinlich meinte er: "Ich hasse es, dem Computer auf weniger intuitive Weise zu sagen, was ich will." :) Tun wir nicht alle? lol.
quelle
Es ist möglich, wenn Sie beim Schreiben Ihres "eigenen" Codes aufpassen. Sie können davon ausgehen, dass Ihr Index für alle n> = 0 bei n beginnt, und entsprechend programmieren.
In Bezug auf Standard hat Borealid ein gutes Argument.
quelle