Warum haben manche Programmiersprachen Nullen und andere Einsen?

Gast #6631603
Lesenswert?

Ich würde gern wissen, warum es unterschiedliche Zählweisen gibt. Bei C 
fängt ein Arrayelement bei Null an und geht bis 15, wenn es 16 Plätze 
hat. Dann gibt es andere Programmiersprachen, da fängt die Zählweise bei 
1 an. Das finde ich verwirrend und ich habe auch schon Fehler gemacht. 
Fatal ist es, wenn ich in C dennoch die [16] adressiere, denn dann kommt 
keine Fehlermeldung. Könnte man das nicht verallgemeinern?
#6631609
Lesenswert?

Wer sich beim Design der Sprache am inneren Ablauf von Computern 
orientiert, beginnt mit 0. Wer sich am menschlichen Verständnis 
orientiert, beginnt bei 1 oder gleich bei einer wählbaren Untergrenze. 
Und wer seine Kundschaft kennt, fängt bei einem 10er-Array bei 0 an und 
endet bei 10 (BASIC).

Und dann gibts noch eine recht skurrile Variante, bei der man die 
Untergrenze im Gesamtprogramm global wählt. Also mit einer globalen 
Einstellung für alle Arrays voreinstellt, ob sie mit mit 0 oder 1 
beginnen (⎕IO in APL). Da liegt die wahre Kunst darin, Programme so zu 
schreiben, dass es nicht drauf ankommt.
#6631711
Lesenswert?

Anfänger schrieb:
> Ich würde gern wissen, warum es unterschiedliche Zählweisen gibt. Bei C
> fängt ein Arrayelement bei Null an und geht bis 15, wenn es 16 Plätze
> hat..... Könnte man das nicht verallgemeinern?
Ja, könnte man. Es wird aber immer solche Sachen geben. Und je schneller 
man sie akzeptiert und nicht nachfragt, desto einfacher wird es. Denn 
auch, wenn es dafür logische Gründe gibt, trotzdem sind diese 
"Unterschiede" da. Und meistens nicht weg zu machen.

Uns stört es nicht, dass wir Erdgeschoß, danach 1, 2 usw. haben. 
Wiederum die Anderen fangen mit 1 an.

Wir sagen einundzwanzig und nicht zwanzugeins usw.
Gast #6631726
Lesenswert?

Speicher fängt auch mit 0 an. Warum? Weil dann ein Zähler komplett 
genutzt werden kann.

Wenn Dein Array von 0..255 geht, kannst Du mit 8 Bit alle adressieren 
UND alle sind gültig.

Das geht mit 1..255 oder 256 nicht.
#6631743
Lesenswert?

A. S. schrieb:
> Speicher fängt auch mit 0 an. Warum? Weil dann ein Zähler komplett
> genutzt werden kann.
>
> Wenn Dein Array von 0..255 geht, kannst Du mit 8 Bit alle adressieren
> UND alle sind gültig.
>
> Das geht mit 1..255 oder 256 nicht.

Es gibt bestimmt sehr viele Gründe dafür und dagegen. Das ist z.B. einer 
, der dafür ist. Aber es war bestimmt einfach eine Idee von jemanden so 
und nicht anders zu machen. Und das hat sich "standarisiert". Denn ich 
muss zugeben, in 30 Jahren noch nie ein Array mit unbedingt nur 255 
Elementen zu haben. Denn, auch wenn man ein Array mit 255 Elementen in 
einer Schleife angeht und dabei auf int achtet, wird man z.B. so was 
schreiben wollen, ...
1
  for (int i=0; i<=255; i++)
2
  {
3
  }
, was nicht zu einem Fehler, jedoch wirklich zu einer endlosen Schleife 
würde, weil die Schleife nie verlassen wird. Zu mind. in c bzw. c++. 
Eine Frage in die Runde - wer kann sagen wieso?
Gast #6631751
Lesenswert?

Sprachen mit 1 sind idealistisch. An Mathe angelehnt oder von 
Professoras entworfen.

Sprachen mit 0 sind auf reale Computer ausgerichtet. An dem was ist, 
nicht wie es sein sollte.



Anfänger schrieb:
> Fatal ist es, wenn ich in C dennoch die [16] adressiere, denn dann kommt
> keine Fehlermeldung.

Dann schalte die Warnungen ein!
#6631752
Lesenswert?

Anfänger schrieb:
Das finde ich verwirrend und ich habe auch schon Fehler gemacht.
> Fatal ist es, wenn ich in C dennoch die [16] adressiere, denn dann kommt keine 
Fehlermeldung. Könnte man das nicht verallgemeinern?
Sorry, ich habe nur den ersten Teil kommentiert. Jetzt der zweite. Mit/ 
bzw. ohne Fehlermeldung.
In einer Sprache um z.B. in so einem Fall diese Fähigkeit implementieren 
zu können muss folgendes passieren. Beim Kompilieren eines c-Programms 
würde eine Stelle vorgesehen, wo die Anzahl der Elemente in einem Array 
abgelegt wird. Danach soll jeder Zugriff auf ein Array-Element geprüft 
werden, ob der Index sich außerhalb des Ranges liegt. Wenn ja, 
Fehlermeldung. Wenn nein, dann auf das Element zugreifen lassen. Das 
"kostet" Zeit. c und c++ sind deswegen schneller als die anderen 
Sprachen, weil dort diese Prüfung nicht gemacht wird. Denn das Programm 
macht das, was Entwickler von dem Programm will. Auch der Zugriff auf 
die "falschen" Elemente gehört dazu. Es gibt wiederum andere Sprachen, 
wo das abgefangen wird, dafür sind sie langsamer.
Gast #6631772
Lesenswert?

Valeri D. schrieb:
> ähnlich wie Diskussion, wann das
> Jahrhundert anfängt? im 0-ten Jahr oder in dem 1-ten.?

Das Problem dabei ist, dass es garkein Jahr 0 gibt, nur 1 vor Christi 
Geburt und 1 nach Christi Geburt, was jeder Mathematik Hohn spricht. Ist 
aber nicht mein Spezialgebiet.

Georg
#6631781
Lesenswert?

(prx) A. K. schrieb:
> Und wer seine Kundschaft kennt, fängt bei einem 10er-Array bei 0 an und
> endet bei 10 (BASIC).
Nö, das ist ein Array mit 11 Elementen, in manchen frühen 
BASIC-Dialekten default. Damals, als die Computer noch mit Gas liefen.
> Und dann gibts noch eine recht skurrile Variante, bei der man die
> Untergrenze im Gesamtprogramm global wählt. Also mit einer globalen
> Einstellung für alle Arrays voreinstellt, ob sie mit mit 0 oder 1
> beginnen (⎕IO in APL).
Auch das gibt es in BASIC,   dort heißt es OPTION BASE.
Gast #6631812
Lesenswert?

Valeri D. schrieb:

> , was nicht zu einem Fehler, jedoch wirklich zu einer endlosen Schleife
> würde, weil die Schleife nie verlassen wird. Zu mind. in c bzw. c++.
> Eine Frage in die Runde - wer kann sagen wieso?

Weil es undefined behaviour ist, wenn das Array mit einer Länge von 255 
am Index 255 beackert wird, und der Compiler daraus alles machen darf, 
was er möchte. Zum Beispiel eine Endlosschleife. Oder alles 
wegoptimieren. Oder schwarzen Kaffee.

Das, worauf Du wohl eigentlich hinaus wolltest, nämlich den Überlauf von 
255 nach Null, findet mit einem int nicht statt, weil ein int in C/C++ 
nicht von 255 nach 0 überläuft. Das hast Du mit einem uint8_t 
verwechselt.
Gast #6631829
Lesenswert?

Hallo

wie auch immer:
Egal welches Format die jeweilige Sprache nutzt - ein Umdenken ist eine 
fehleranfällige Quälerei.
Mit der Null anfangen zu "zählen" ist für einen "Normalmensch" der aber 
technikaffin und neugierig ist und durchaus Spaß an der Sache 
"Programmieren"  an sich haben wird (manchmal auch ein klein wenig als 
reiner Selbstzweck - warum auch nicht?!) ohne das er vorher mit der 
Digitaltechnik oder eben Hardwarenahen Programmierung Kontakt hatte eher 
schwierig - aber schnell erkennt man die Logik und Vorteile dahinter.

Es gibt aber halt auch die "Anderen" - da ist die Programmiersprache nur 
ein notwendiges Übel und je desinteressierter (wenn er ehrlich zu sich 
selbst und anderen ist) der Nutzer ist und je mehr es um eine "einfache" 
(oft Grafische oder "Kinderkonforme") Sprache geht umso mehr Sinn macht 
es ganz "normal" zu zählen - die letztendlich hinter allen (?) 
Hardwarenahen Programmiersprache stehende Digitaltechnik bis herunter zu 
den Logikgattern und auch die sehr hilfreiche aber auch extrem abstrakte 
Boolsche Algebra (die bis man sie versteht absoluter scheinbar 
sinnfreier Horror ist, besonders wenn man schon die Schulalgebra nie 
wirklich verstanden hat ) ist für diesen Nutzerkreis von keinerlei 
Belang - es interessiert ausschließlich das Ergebnis und nicht das "Wie 
und Warum" oder ob der Weg dahin optimal gewählt wurde (Hardwareleistung 
kompensiert das locker...)
Warum sollten sich diese Leute dann selbst das Leben schwer machen und 
mit Null anfangen zu zählen?
Wobei das Zählen ja noch die kleinste Hürde ist, die Probleme fangen 
dann richtig an wenn gerechnet werden muss und die (erst mal) seltsame 
Logik dahinter angewendet werden muss.
Entsprechend wird dann die passende Programmiersprache gewählt (soweit 
möglich und nicht aufgezwungen...)

Jemand
Gast #6631833
Lesenswert?

Valeri D. schrieb:
> Aber es war bestimmt einfach eine Idee von jemanden so und nicht anders
> zu machen. Und das hat sich "standarisiert".
Du kannst sicher sein, dass den Vätern der Sprachen die Argumente 
bekannt waren und keine Entscheidung hierzu leichtfertig war.

> Denn ich muss zugeben, in
> 30 Jahren noch nie ein Array mit unbedingt nur 255 Elementen zu haben.

Dann hast Du vermutlich wenig rechnernah gemacht: sonst wäre dir der 
Wert für 2^8 bekannt (256 Elemente, uint8<=256 als Endlosschleife).

Und auch nicht embedded, dort sind Ring-Puffer mit 2^n Elementen häufig.
#6631900
Lesenswert?

Georg schrieb:
> Valeri D. schrieb:
>> ähnlich wie Diskussion, wann das
>> Jahrhundert anfängt? im 0-ten Jahr oder in dem 1-ten.?
>
> Das Problem dabei ist, dass es garkein Jahr 0 gibt, nur 1 vor Christi
> Geburt und 1 nach Christi Geburt, was jeder Mathematik Hohn spricht. Ist
> aber nicht mein Spezialgebiet.

Das liegt daran, dass das aus einer Zeit stammt, als die 0 als Zahl noch 
nicht "erfunden" war. Das bedeutet übrigens auch, dass das Jahrtausend 
eigentlich erst mit dem Wechsel von 2000 nach 2001 rum war und alle das 
ein Jahr zu früh gefeiert haben. Aber Datum und Uhrzeit ist da eh 
speziell. Der Tag fängt mit Stunde 0 an, die Stunde mit Minute 0 und die 
Minute mit Sekunde 0. Der Monat fängt aber mit Tag 1 an und das Jahr mit 
Monat 1.
#6632031
Lesenswert?

(prx) A. K. schrieb:
> Sicher. Aber DIM(10) zu schreiben, um ein Array mit 11 Elementen zu
> definieren, ist ja nicht unbedingt naheliegend.

Richtig, die Sprachbeschreibung sieht DIM A!([1 TO] 10) oder DIM B!([0 
TO] 9) vor. Deshalb ist es sinnvoll, sich über die defaultmäßige untere 
Grenze vorab zu informieren.

In den alten MS-BASIC-Versionen , von denen Du zu sprechen scheinst (und 
anderen auch), brauchten Variable aber nicht deklariert zu werden - eine 
schier unerschöpfliche Fehlerquelle. Das galt auch für Arrays: wurden 
sie einfach durch Gebrauch eingeführt, dann nahm der Interpreter die 
Dimensionierung ARRAY(0 TO 10) vor.

Wer hingegen selbst die Dimensionen definieren wollte, der durfte auch 
beide Grenzen angeben. Für denjenigen, der gern die untere Grenze 
weglassen wollte, bot sich der OPTION BASE-Befehl an. Der hatte dann 
allerdings den Nachteil, dass nach OPTION BASE 1 ein DIM A!(0 TO 5) zu 
einem Laufzeitfehler führte (wozu auch sonst bei einem Interpreter ...).

Oder man arbeitete eh mit der unteren Grenze 0, was sehr häufig ohnehin 
sinnvoll war. Man musste es bloß wissen.

Notabene: das bezieht sich auf MS. Bei Apple, TRS-80  oder Commodore mag 
es anders gewesen sein.
Gast #6632039
Lesenswert?

Jemand schrieb:
> Es gibt aber halt auch die "Anderen" - da ist die Programmiersprache nur
> ein notwendiges Übel

Es sind keineswegs alle blöd die nicht mit 0 anfangen zu addressieren. 
In Pascal gibt es schon immer Arrays [8..25] usw., und man kann dem 
Compiler sagen dass er das zur Laufzeit auch prüfen soll. Das erspart 
nicht nur eigene Umrechnungen, sondern vermeidet auch Fehler dabei.

Aber für C-Fanatiker ist halt jemand der eine andere Sprache verwendet 
kein echter Programmierer, sondern bloss ein Depp.

Georg
Gast #6632062
Lesenswert?

Rolf M. schrieb:
> Das liegt daran, dass das aus einer Zeit stammt, als die 0 als Zahl noch
> nicht "erfunden" war.

Interessanter Aspekt, allerdings nicht ganz korrekt. Zumindest 
Mitteleuropa schien sich mit 'Erfindung' der Null Zeit zu lassen. In 
Indien dagegen wird die Genesis der Null in das 3. Jahrhundert vor 
Christus gelegt.

In Deutschland wird Adam Ries (1492 -  1559) als Initiator der 
Null-Rechnung geführt.
Moderator #6632359
Lesenswert?

Es gibt Kardinalzahlen (1 Apfel, 2 Äpfel oder 3 Äpfel im Korb) und
Ordinalzahlen (das 1. Haus, das 2. Haus oder das 3. Haus in der Straße).

Die alten Griechen und die Römer kannten noch keine Null und erst recht
keine negativen Zahlen, somit waren die kleinste Kardinalzahl und die
kleinste Ordinalzahl beide 1.

Irgendwann hat so ein Weltenbummler von seiner Reise nach Indien als
Souvenir die Null mitgebracht. Damit konnte nun endlich auch einem
leeren Korb eine Anzahl von Äpfeln (nämlich 0 Äpfel) zugewiesen werden.

Das 1. Haus in der Straße blieb aber bis heute das 1. Haus, von einem 0.
Haus redet praktisch niemand.

Das zusätzliche Element in der Menge der Kardinalzahlen stört im
normalen Sprachgebrauch kaum. In der klassischen Mathematik beginnen
sowohl die Kardinalzahlen (Menge ℕ der natürlichen Zahlen) als auch die
Ordinalzahlen (bspw. Indizes von Folgen- oder Vektorelementen) wie bei
den alten Griechen bei 1. Selbst wenn man die 0 mit zu den natürlichen
Zahlen nimmt, die Indizes aber nach wie vor bei 1 starten lässt, ist das
kein Problem, dann ist eben ℕ=ℕ₀ und die Indizes werden aus der Menge ℕ⁺
entnommen.

Im Typsystem von Programmiersprachen wird aber selten zwischen Kardinal-
und Ordinalzahlen unterschieden. Derselbe Integer-Typ kann üblicherweise
sowohl als normaler Zahlenwert als auch als Index genutzt werden, was ja
auch ganz praktisch ist. Da man bei den Kardinalzahlen nicht auf die
Null verzichten möchte, ist die Null wegen des einheitlichen Datentyps
auch als Ordinalzahl verfügbar. Deswegen bietet es sich an, unabhängig
von Hardwareaspekten (Speicheradressen starten meist ebenfalls bei 0)
die Null auch als Array-Index zu nutzen.

So ist der Startindex bei den meisten Programmiersprachen, in denen er
nicht – wie bspw. in Pascal, Ada und Haskell – frei wählbar ist,
tatsächlich 0. Das gilt auch für nicht hardwarenahe Sprachen wie bspw.
Python, Common Lisp usw.

Eine der wenigen Ausnahmen bildet Fortran: Dort starten Array-Indizes –
der Konvention der klassischen Mathematik folgend – bei 1. Seit Fortran
77 kann aber in der Array-Deklaration optional auch ein anderer (auch
negativer) Startindex angegeben werden.

Auch in Matlab starten die Array-Indizes bei 1, was m.W. auch nicht
geändert werden kann.

Ein (wenn auch kein ernstes) Problem bei der Indizierung ab 0: Wenn
jemand vom dritten Array-Element von a spricht, ist nicht immer ganz
klar, ob er a[2] oder a[3] meint.

Wenn ich Josef G. wäre, würde ich deswegen dafür werben, Kardinalzahlen
auch in natürlichen Sprachen bei 0 beginnen zu lassen. Das erste Haus in
der Straße wäre nach der neuen Konvention also das nullte Haus, der
erste, der beim 100m-Lauf die Ziellinie überschreitet, wäre dann der
Nullte, die erste Klasse im Bahn- und Flugverkehr die nullte Klasse, die
First Lady eines Staats die Zeroth Lady usw. ;-)
Gast #6632369
Lesenswert?

Also ich hatte mir das - bei C - immer so erklärt, dass array[0] als 
Zeiger auf die Startardresse des Feldes und somit auf das erste Element 
zeigt. Ebenso weiter bedeutet array[n], dass ich zur Startadresse n-mal 
weitergehe (Startpointer + n) und somit auf das n+1-te Element zeige. 
Ist nicht mit Hausnummern o.ä. kompatibel, ergibt aber m.E. aus Sicht 
der Umsetzung im Speicher Sinn.

Btw: Man hat schon C-Programmierer im Aufzug auf die 2 drücken sehen, 
wenn sie in den dritten Stock wollten.
#6632392
Lesenswert?

>Also ich hatte mir das - bei C - immer so erklärt, dass array[0] als
>Zeiger auf die Startardresse des Feldes und somit auf das erste Element
>zeigt. Ebenso weiter bedeutet array[n], dass ich zur Startadresse n-mal
>weitergehe (Startpointer + n) und somit auf das n+1-te Element zeige.
>Ist nicht mit Hausnummern o.ä. kompatibel, ergibt aber m.E. aus Sicht
>der Umsetzung im Speicher Sinn.

Sehr gut erkannt.
#6632402
Lesenswert?

Tom schrieb:
> Ebenso weiter bedeutet array[n], dass ich zur Startadresse n-mal
> weitergehe (Startpointer + n) und somit auf das n+1-te Element zeige.

Genau so ist a[i] in C definiert, als *(a+i), weshalb aufgrund der 
Kommutativität der Addition i[a] zwar unkonventionell ist, aber 
zulässig. Statt "0123456789"[3] kannst du also auch 3["0123456789"] 
schreiben.
Moderator Persönliche Seite #6632581
Lesenswert?

Hans-Georg L. schrieb:
> Du bist dir darüber im klaren das der Array Index in C signed ist.

So ist es. Negative Indices sind in C durchaus möglich.

Beispiel:
1
    uint8_t a[256];
2
    uint8_t * p;
3

4
    p = a + 20;   // gehe mit p 20 Bytes weiter
5
    p[-3] = 4;    // speichere von dort aus gesehen 3 Bytes davor den Wert

(prx) A. K. schrieb:
> Genau so ist a[i] in C definiert, als *(a+i)

Analog ist a[-i] in C als *(a - i) definiert.

Unter diesem Kontext ist es nur logisch, dass a[0] oder auch p[0] das 
"aktuelle Element" ist - ich vermeide hier mal bewusst die Bezeichnung 
"erstes Element".
Gast #6632731
Lesenswert?

Hans-Georg L. schrieb:
> Experte schrieb:
>> Wobei ich früher Arrays beginnend bei "1" auch komisch fand, bin ich
>> inzwischen aber auch anderer Meinung: Der Index "0" lässt sich wunderbar
>> als "nicht gültig" missbrauchen.
>
> Du bist dir darüber im klaren das der Array Index in C signed ist.

Darüber bin ich mir sehr im Klaren. Das war aber nicht mein Punkt.

Die "0" als "nicht gefunden", "ungültiger Index", etc. hat eine 
intrinsische Eleganz. Auch der Umgang mit Array-Längen zerfällt bei 
einem Start-Index von "1" zu natürlicher Schönheit.

Nun kann man das alles als unwichtiges Beiwerk betrachten. Wenn man sich 
allerdings vor Augen führt, dass es für einen 
Compiler/Interpreter/Sprachstandard irrelevant ist, ob der Start-Index 
"0" oder "1" ist, ist selbiges für Menschen nicht gleichgültig. Denn 
Menschen fangen nun mal bei "1" an zu zählen. Und die wichtigste 
Eigenschaft einer Programmiersprache ist es, dass der Programmierer 
(Mensch!) seine Intention mit möglichst wenig "Medienbrüchen" 
("Denkbrüchen") beschreiben kann.

Ja, in den meisten genutzten Programmiersprachen wird der 
Programmierer-Padawan auf die heilige "0" als Start-Index gedrillt. 
Frühkindliche Prägung sozusagen, so wie die Küken bei Konrad Lorenz (das 
war doch Konrad Lorenz, oder?). Da fällt es nicht so leicht, auch mal 
über den Tellerrand zu blicken und zu hinterfragen, ob das eigentlich 
eine "gute" Marotte der gängigen Programmiersprachen ist.
Beitrag #6632766 wurde von einem Moderator gelöscht.
Moderator Persönliche Seite #6632773
Lesenswert?

Experte schrieb:
> Ja, in den meisten genutzten Programmiersprachen wird der
> Programmierer-Padawan auf die heilige "0" als Start-Index gedrillt.

Das Leben wird für einen Programmierer (und auch für die verwendete CPU) 
mit einem Array, das mit dem Index 0 beginnt, in vielen Fällen 
wesentlich einfacher.

Zum Beispiel, wenn ein Array-Index sich aus einer Multiplikation oder 
einer Modulo-Operation ergibt, ist alles viel einfacher, wenn das Array 
mit 0 beginnt. Und ja, solche Situationen gibt es öfters, egal ob es um 
Bildverarbeitung, Bildung von Hash-Werten oder um Zufallszahlen geht.

Ich persönlich keine keinen einzigen Vorteil bei einem Index beginnend 
mit 1, bei einem Index beginnend mit 0 aber einige.

Kennst Du einen Vorteil, der für 1 spricht?
#6632780
Lesenswert?

Frank M. schrieb:
> Kommt wohl auf dasselbe hinaus ;-)

Nein.

(prx) A. K. schrieb:
> Im üblichen 64-Bit Datenmodell mit i als 32-Bit Integer und p als 64-Bit
> Pointer wird bei (p+(-i)) zunächst -i in 32 Bits berechnet und das
> Ergebnis auf 64 Bits erweitert.

Bei i==INT_MIN ist folglich das Ergebnis von (p+(-i)) aufgrund von 
Overflow undefiniert, bei (p-i) hingegen definiert.
Moderator Persönliche Seite #6632790
Lesenswert?

(prx) A. K. schrieb:
> Im üblichen 64-Bit Datenmodell mit i als 32-Bit Integer und p als 64-Bit
> Pointer wird bei (p+(-i)) zunächst -i in 32 Bits berechnet und das
> Ergebnis auf 64 Bits erweitert.

Und ist da ein Unterschied für positive Werte für i? Ich habe ja das 
negative Vorzeichen des Indices bewusst aus i "rausgezogen", als ich 
schrieb:

> Analog ist a[-i] in C als *(a - i) definiert.

Habs gerade mal getestet:
1
#include <stdio.h>
2
#include <stdint.h>
3

4
int main ()
5
{
6
    int i;
7
    uint8_t * p;
8

9
    printf ("sizeof(int) = %lu\n", sizeof (i));
10
    printf ("sizeof(ptr) = %lu\n", sizeof (p));
11
    printf ("sizeof(ul) = %lu\n", sizeof (unsigned long));
12

13
    p = (uint8_t *) 0x123456789abcdef0;
14
    i = 256;
15

16
    printf ("0x%16lX 0x%16lX\n", (unsigned long) (p + (-i)), (unsigned long) (p - i));
17

18
    return 0;
19
}
1
# cc -O2 -Wall -Werror a.c && ./a.out
2
sizeof(int) = 4
3
sizeof(ptr) = 8
4
sizeof(ul) = 8
5
0x123456789ABCDDF0 0x123456789ABCDDF0

Für mich gibts da keinen Unterschied, aber vielleicht habe ich ja 
falsche Werte benutzt und Du hast ein treffenderes Gegenbeispiel.

EDIT:

Programm um sizeof (unsigned long) ergänzt.
Gast #6632813
Lesenswert?

Frank M. schrieb:
> Kennst Du einen Vorteil, der für 1 spricht?

Eher Nachteile, die gegen die 0 sprechen :-) Es ist schon sinnvoll, wenn 
das 1ste Element den Index 1 hat und nicht 0. Klar lernt man leicht, 
dass 1756 im 18ten Jahrhundert war, aber es ist einfach nicht intuitiv. 
Und wenn ich mein Umfeld so anschaue, werden in diesem Belang auch 
häufig Flüchtigkeitsfehler gemacht.

Nach meiner Erfahrung würde ich sagen in grob 50% der Fälle ist die 1 
besser, in 50% die 0. Bei hardwarenaher Programmierung, wo man mit 
Zeigern, Arrays usw. jongliert, liegt die 0 vorne. Bei reinen 
Arrayoperationen dagegen die 1. Allerdings sollte man sich auch wenn man 
die Wahl hat auf eines beschränken, sonst kommt man durcheinander. In 
Pascal werden die Zeichen in Strings von 1 an indiziert, dynamische 
Arrays von 0 an. Ich find das ganz ok, sind ja auch unterschiedliche 
Dinge.
1
for ii:= 0 to length(SomeArray) -1 do // <- das -1 ist unschön und fehlerträchtig
1
count:= count + 1;
2
SomeArray[Count-1]:= ...  //das -1 ist unschön und fehlerträchtig
1
SomeArray[Count]:= ...    //man operiert hier eigentlich mit einem falschen Count -> fehlerträchtig
2
count:= count + 1;
Gast #6632826
Lesenswert?

Udo S. schrieb:
> Eine absolut bescheuerte Ursprungsfrage (vor allem auch die
> Überschrift), aber kurz danach machen 3 Moderatoren und andere
> kompetente Forumsteilnehmer mit.
>
> Der Tread bekommt von mir 10 von 10 Trollpunkten!
> :-)

Von mir auch. Verstehe nicht, warum auch nur eine/einer geantwortet hat.
#6632833
Lesenswert?

Frank M. schrieb:
> Für mich gibts da keinen Unterschied, aber vielleicht habe ich ja
> falsche Werte benutzt und Du hast ein treffenderes Gegenbeispiel.
1
#include <stdio.h>
2
#include <stdint.h>
3
#include <limits.h>
4

5
volatile int i = INT_MIN;
6

7
int main ()
8
{
9
    uint8_t * p;
10
    p = (uint8_t *) 0x123456789abcdef0;
11
    printf ("0x%16lX\n", (unsigned long) (p - i));
12
    printf ("0x%16lX\n", (unsigned long) (p + (-i)));
13
    return 0;
14
}

Bei gcc -ftrapv:
1
0x123456791ABCDEF0
2
Abgebrochen
Hintergrund: Die Rechnung -INT_MIN ist hier undefiniert, weil Überlauf 
bei Rechnung mit Vorzeichen. Mit -ftrapv wird das zur Laufzeit 
überprüft.

Wenn Code sich mit -ftrapv anders verhält als ohne, ist er undefiniert.
Gast #6632861
Lesenswert?

Georg schrieb:
> Es sind keineswegs alle blöd die nicht mit 0 anfangen zu addressieren.
> In Pascal gibt es schon immer Arrays [8..25] usw., und man kann dem
> Compiler sagen dass er das zur Laufzeit auch prüfen soll. Das erspart
> nicht nur eigene Umrechnungen, sondern vermeidet auch Fehler dabei.

Speicher oder Arrays mit 1 anzufangen, ist intuitiver. Darum hat es 
tausende Jahre gedauert, die 0 zu entdecken. Das Problem beim 
Dezimalsystem ist:

Wir haben 11 Symbole für das Dezimalsystem. Damit fangen wir mit 1 an 
und haben trotzdem noch 10 Werte und die 0 zusätzlich.

Im Binärsystem ist das anders: Mit 5 Fingern wollen wir von 0 bis 31 
Zählen können. Und dabei haben wir kein Symbol über!

Sobald man sich diesen Unterschied klar macht, ist die 0 als Startwert 
unausweichlich.

Stellt Euch vor, wir hätten 16 Finger und ein Byte hätte 4 Bit: Dann 
würden wir wie selbstverständlich bei 1 anfangen, zählten bis 16 und 
hätten dort 2 Alternativen wie bei 24:00 und 0:00.

Mit einem 10-Bit Digitalzähler kann ich halt nur von 0 ... 1023 Zählen. 
Nicht von 1 bis 1024.

Von daher: Ja, es ist gut, Umrechnungen zu vermeiden. Doch dann doch 
lieber gleich im Dezimalsystem, denn dort (mit 10 Fingern + 0) macht die 
Definition des Elfenbeinturms Sinn.
Moderator Persönliche Seite #6632870
Lesenswert?

Frank M. schrieb:
> Und ist da ein Unterschied für positive Werte für i? Ich habe ja das
> negative Vorzeichen des Indices bewusst aus i "rausgezogen", als ich
> schrieb:
>> Analog ist a[-i] in C als *(a - i) definiert.

(prx) A. K. schrieb:
> volatile int i = INT_MIN;

Das gilt nicht ;-)

INT_MIN ist negativ. Ich hatte das obige für positive i geschrieben. 
Das Vorzeichen hatte ich bewusst davorgesetzt, um das Analogon für einen 
negativen Index (Minus vor positivem i) zu hinzuschreiben. Eigentlich 
wäre genau INT_MIN die passende Konstante, um einen ungültigen Index zu 
definieren ;-)

Aber egal, dieser Spezialfall hat für mich sowieso nur noch akademischen 
Wert.
Gast #6632899
Lesenswert?

(prx) A. K. schrieb:
> Hintergrund: Die Rechnung -INT_MIN ist hier undefiniert, weil Überlauf
> bei Rechnung mit Vorzeichen. Mit -ftrapv wird das zur Laufzeit
> überprüft.

Rechnen mit Pointern, die nicht auf existierende Objekte zeigen, ist 
auch ohne INT_MIN zweifelhaft, vermutlich sogar UB.

A. S. schrieb:
> Speicher oder Arrays mit 1 anzufangen, ist intuitiver. Darum hat es
> tausende Jahre gedauert, die 0 zu entdecken.

Du hast vermutlich noch nicht allzuviele Indices in mehrdimensionale 
Arrays berechnet. Nachdem man das mal in C gemacht hat, möchte man nie 
wieder zurück zu FORTRAN.
Gast #6632908
Lesenswert?

Hallo

Tom schrieb:
> Btw: Man hat schon C-Programmierer im Aufzug auf die 2 drücken sehen,
> wenn sie in den dritten Stock wollten.

(prx) A. K. schrieb:
>> der erste, der beim 100m-Lauf die Ziellinie überschreitet,
>
> ... ist also eine Null.


Wenn das auch wohl witzig ironisch gemeint sein dürfte (Ist es durchaus 
auch) so zeigt das durchaus ernsthaft wie schnell ein einmal in Fleisch 
und Blut übergegangenes System zum "Problem" werden kann und es einfach 
nicht "das" bessere Zähl- bzw. Rechensystem geben kann.
Am besten bleibt man seinen System treu und unterlässt alle Grabenkämpfe 
und Wertung oder gar Belehrungen von Hobby- und Profikollegen die eine 
andere Programmiersprache verwenden.

Jemand
Gast #6632914
Lesenswert?

mh schrieb:
> A. S. schrieb:
>> Speicher oder Arrays mit 1 anzufangen, ist intuitiver. Darum hat es
>> tausende Jahre gedauert, die 0 zu entdecken.
>
> Du hast vermutlich noch nicht allzuviele Indices in mehrdimensionale
> Arrays berechnet. Nachdem man das mal in C gemacht hat, möchte man nie
> wieder zurück zu FORTRAN.

Vielleicht hast Du den Text darum herum nicht gelesen: Es ist 
intuitiver, wenn man erstmals eine Programmiersprache entwickelt. Aber 
mit ein bisschen Nachdenken und Erfahrung

A. S. schrieb:
> ist die 0 als Startwert unausweichlich.
(Firma: Funkenflug Industries) #6633016
Lesenswert?

Ach ja... das alte Thema mit den off-by-one errors.

Ich würde jedem Programmierer empfehlen, sich streng an "ersten Index 
Null" zu halten oder wie man das am besten kurz beschreiben soll. Das 
gibt am wenigsten Probleme damit. Wenn eine Programmiersprache das nicht 
kann (kenne keine), würde ich sie entsorgen und mir was anderes 
aneignen.

Wenn man mal auf einen Fall stößt wo 1 als erster Wert sehr sinnvoll 
ist, kann man das ja immer noch machen - sollte das dann aber sehr gut 
dokumentieren.
#6633052
Lesenswert?

Eine sehr gute Diskussion. Habe für mich sehr viel erfahren. Zur 
Aufklärung haben einige Redner sehr viel beigetragen. Ja, und der Rest 
der Diskussion, was besser und was schlechter; 0 oder 1 - finde ich 
persönlich überflüssig. Bzw. man soll die Unterschiede ein wenig locker 
annehmen. Denn solche Unterschiede findet man überall - in der 
Menschensprache, in der Zählweise, in den Essenskulturen bzw. in der 
Gestik dieser versch. Kulturen usw.

Ja, man kann sich auch dagegen stellen. Man kann das aber auch "positiv"
akzeptieren als normal empfinden und zum Besseren drehen.

Wenn aber einem eine Technologie oder ein System wirklich gar nicht 
"schmeckt", nun, dann kann man sein Eigenes probieren. Das hat Steve 
Wozniak mit seiner Platine bewiesen. Das hat Linus Torvalds mit seinem 
Betriebssystem bewiesen. Das hat Elon Musk schon mehrere Male bewiesen. 
Und viele anderen. Somit - ja, man muss nicht alles akzeptieren.

Aber darüber zu streiten, welche Sprach-Konstruktion die Beste ist - 
führt zu nichts. Egal, ob es sich dabei um Programmiersprache oder 
Menschensprache handelt. Ein Beispiel aus der deutschen Sprache - 
trennbare Verbe. Ist das gut oder schlecht? Ich würde sagen - mir ist 
diese Bewertung egal. Denn ich empfinde das als was Besonderes in der 
Sprache. Kaum eine Sprache hat so was. Und wir wenden es an, ohne 
nachzudenken.
#6633073
Lesenswert?

Ich siehe das wie bei einem 1m langen Holzlineal.
Der Meter ist in 100 cm unterteilt.

https://www.amazon.de/erhalten-solide-gekennzeichnet-doppelte-Holzlineal/dp/B07CGF9T76/ref

Der 1. Teilstrich geht von 0 bis 0,99.. cm (lässt man die Kommastellen 
weg, erhält man 0)
der 2. von 1 bis 1,99.. cm (lässt man die Kommastellen weg, erhält man 
1)

Der Index ist int(s), wobei s die Strecke vom Beginn des Maßstabes bis 
zur gemessenen Stelle ist.
#6633089
Lesenswert?

Gerald K. schrieb:
> Ich siehe das wie bei einem 1m langen Holzlineal.
> Der Meter ist in 100 cm unterteilt.
>
> 
https://www.amazon.de/erhalten-solide-gekennzeichnet-doppelte-Holzlineal/dp/B07CGF9T76/ref
>
> Der 1. Teilstrich geht von 0 bis 0,99.. cm (lässt man die Kommastellen
> weg, erhält man 0)
> der 2. von 1 bis 1,99.. cm (lässt man die Kommastellen weg, erhält man
> 1)
>
> Der Index ist int(s), wobei s die Strecke vom Beginn des Maßstabes bis
> zur gemessenen Stelle ist.

meinst du - kann man dein Lineal mit dem Index in einem Array 
vergleichen? Ich sage - sie haben miteinander nichts zu tun. In einem 
habe ich Werte bzw. Stellen auch dazwischen, denn dafür ist der Messstab 
auch vorgesehen. In dem anderen habe ich präzise Werte wie z.B. 0, 1, 2 
usw. Und ich meine nicht, ob 0 oder 1. Sondern die Tatsache, dass dieses 
Beispiel vollkommen hinkt. Ein Index ist niemals eine Strecke, niemals 
die Zeit zu der Stelle, niemals eine Geschwindigkeit oder Dauer usw. Ein 
Index ist ein Index. Eine Nummerierung einer Speicherzelle bzw. -stelle.

Denn die Aussage (lässt man die Kommastellen weg...) ist vollkommen 
künstlich. Aus der Serien "Gedanken Experimente". Wenn ein Man jemals 
schwanger sein würde, dann würde er auch gebären können. Ja, würde er, 
aber bitte zuerst den ersten Teil erfüllen.
#6633119
Lesenswert?

Adam P. schrieb:
> Anfänger schrieb:
>> Könnte man das nicht verallgemeinern?
>
> Klar:
>
> 0 ist die erste positive Zahl, fertig.

Evtl. die die richtige Erklärung.

Ein wenig zum Lächeln. Denn die Autoren von dem IEEE 754 für die 
Darstellung der Gleitkommazahlen würden mit dir nicht einverstanden sein 
:)

Denn laut dieser Formatierung gibt es auch -0. Die Zahl in 32 bits sieht 
so aus 10000000000000000000000000000000 - d.h. 0 aus ihrer Sicht kann 
nicht nur positiv sein.
Gast #6633129
Lesenswert?

Adam P. schrieb:
> Anfänger schrieb:
>> Könnte man das nicht verallgemeinern?
>
> Klar:
>
> 0 ist die erste positive Zahl, fertig.

Nein, Null ist das neutrale Element in dieswer (algebraischen) Struktur 
und keine (positive) Zahl. 0 zählt zu den nichtnegativen Zahlen.

Wobei es für einen array-index keine Zahlenbereich benötigt, sondern 
lediglich eine abzählbare Menge.
Deshalb wird ja ion manchen Sprachen auch ein enumeration als Index 
eingesetzt.

https://stackoverflow.com/questions/404231/using-an-enum-as-an-array-index
https://www.fluentcpp.com/2019/01/15/indexing-data-structures-with-c-scoped-enums/
https://de.wikipedia.org/wiki/Neutrales_Element
Gast #6633139
Lesenswert?

(prx) A. K. schrieb:
> Fpgakuechle K. schrieb:
>> 0 zählt zu den nichtnegativen Zahlen.
>
> Selbst wenn sie ein negatives Vorzeichen haben sollte. ;-)

Genau. Weil eine -0 ist keine Zahl, sonder das smiley für Punk mit 
Irokesenschnitt von hinten  };-)


PS:
Wenn was ernstahftes zu -0 und 0 als Zahlendarstellung in der 
rechentechnik sollte man unter 2er Komplement und Artverwandte 
nahschlagen.
https://de.wikipedia.org/wiki/Zweierkomplement
Gast #6633162
Lesenswert?

Valeri D. schrieb:
> . Ja, und der Rest der Diskussion, was besser und was schlechter; 0 oder
> 1 - finde ich persönlich überflüssig.

Das ist wie Gabel oder Löffel: wer nur Kartoffelbrei ist, empfindet es 
als Geschmackssache. Wer nur Suppe kennt, kann die Spaghetti-Esser nicht 
verstehen.

Wann 0 und wann 1 besser ist, wurde ja gesagt.

Wie bei little oder big endian: egal was ich lieber habe, konkrete 
hw-eigenschaften machen big endian zu legacy.
#6633544
Lesenswert?

Georg schrieb:
> Valeri D. schrieb:
>> In dem anderen habe ich präzise Werte wie z.B. 0, 1, 2
>> usw.
>
> Du bist wohl noch nie vom Gleis 9 3/4 abgefahren.
>
> Übrigens habe ich auch noch keinen Bahnhof mit einem Gleis 0 gesehen.
>
> Georg

:)
Im Düsseldorfer Hauptbahnhof gibt es keine Gleise mit den Nummern 1 – 3 
und 8. Diesen Zustand sollen wir für unsere Array-Zählung auch 
einsetzen.
Beitrag #6633550 wurde von einem Moderator gelöscht.
Beitrag #6633562 wurde von einem Moderator gelöscht.
Gast #6633576
Lesenswert?

Fpgakuechle K. schrieb:
> mh schrieb:
>> Fpgakuechle K. schrieb:
>>> Wobei es für einen array-index keine Zahlenbereich benötigt, sondern
>>> lediglich eine abzählbare Menge.
>>
>> Gibt es einen Grund, warum die Menge abzählbar sein muss?
>
> Damit man Nachfolger und Vorgänger identifizieren kann?!

Ok, das ist praktisch, hat aber wenig mit abzählbar zu tun.
Gast #6633587
Lesenswert?

Percy N. schrieb:
> Fpgakuechle K. schrieb:
>> Damit man Nachfolger und Vorgänger identifizieren kann?!
>
> Jede nichtleere endliche Menge ist abzählbar, zB auch {Hund, Katze,
> Maus}. Woher nimmst Du hier die Ordnungsrelation?

Bspw. in der Abfolge v.li.n.re der Definition der Elemente, also Hund < 
Katze < Maus.

Abzählbarkeit bedeutet, doch das man die Menge 'durchnummerierbar' ist, 
beinhaltet aber nicht die Nummerierung selbst, oder eine spezielle 
Numerierungsweise selbst. Man braucht eben nicht nur eine Zahlenmenge 
als index, sonder in dieser menge müssen auch gewisse Relationen 
definiert sein.
In der Zoologie der algebraischen Strukturen/Gruppen sollte sich auch 
der dazu passende Begriff finden lassen:
https://de.wikipedia.org/wiki/Gruppe_(Mathematik)

Oder in ähnlichen Axiomensystemen, wie das des Peano.
Das ist aber nicht mein Spezialgebiet, ich verweise da lieber auf die 
Praxis im Umgang mit den Index-Konzepten der verschiedenen 
Computersprachen. VHDL als Ada-Abkömmling ist da recht gut strukturiert, 
das bringt attribute für den niedrigste und Höchste Index etc. pp mit.

https://www.tu-ilmenau.de/fileadmin/public/iks/files/lehre/ihs/VHDL_Kurzbeschreibung.pdf 
S.17 f.
Gast #6633588
Lesenswert?

Hat sich in den 20 Jahren etwas an C geaendert was Arrays betrifft?

Weil ansonsten sind "arrays" in C immer noch nur Zeiger auf Adressen, 
Adresse + groesse eines Elementes mal Nummer des Elementes ist der 
Index, Adresse + 0 ist eben der Anfang des Arrays.

Viele Sprachen halten an alten Konventionen fest, ohne echten Grund.
#6633596
Lesenswert?

Fpgakuechle K. schrieb:
> Bspw. in der Abfolge v.li.n.re der Definition der Elemente, also Hund <
> Katze < Maus.
Die ist zufällig!
> Abzählbarkeit bedeutet, doch das man die Menge 'durchnummerierbar' ist,
> beinhaltet aber nicht die Nummerierung selbst, oder eine spezielle
> Numerierungsweise selbst.
So ist es.
> Man braucht eben nicht nur eine Zahlenmenge
> als index, sonder in dieser menge müssen auch gewisse Relationen
> definiert sein.
Richtig!
> In der Zoologie der algebraischen Strukturen/Gruppen sollte sich auch
> der dazu passende Begriff finden lassen:
> https://de.wikipedia.org/wiki/Gruppe_(Mathematik)

Ein geordneter Körper wäre schon was ...
Gast #6633657
Lesenswert?

Fpgakuechle K. schrieb:
> Naja, das Festhalten an der Konvention ist gerade das , was das Ganze
> 'stabilisiert' und damit überhaupt seine deterministische Existenz
> ermöglicht. Zugespitzt formuliert: Ohne (überdauernde) Regeln nur Chaos.

Da hast du natuerlich recht, Konsistenz ist wichtig in verschiedenen 
Versionen einer Sprache.

Ich hab mich da nicht genau ausgedrueckt, fuer Java zB. gab es keinen 
Grund weiterhin bei 0 anzufangen, man wollte aehnlich zu C bzw. C++ 
sein, aber innovativ sein ist eben das Gegenteil von "sich an bestehende 
Konventionen halten".
(Firma: Privat) #6633763
Lesenswert?

Warum fangen dann Listen bei Microsoft
(Listbox, ImageList usw.) auch bei 0 an ?
Also erste Zeile oder erstes Image an Stelle 0 ?
Auch die Zählgeschichten, wie Count, wo man dann
mit count -1 die richtige Anzahl erhält.

Ich finde die 0 als richtiger. Ist mir schon öfter passiert,
wenn ich ein Array mit 1 angefangen hatte, daß ich den
Index  mit +1 oder -1 korrigieren mußte. z.B. ein Array mit
gültigen positiven Werten (1-10).

WhileLoop 0, 9
  Array[&LOOP + 1] = ....
EndWhile

Kommt daher auch immer auf den Einsatz-Zweck an.
#6633782
Lesenswert?

Georg schrieb:
> Das ist garkeine hinreichende Anforderung, denn es gibt abzählbar
> unendliche Mengen, aber keinen Computer der ein unendliches Array
> speichern könnte.

Dieses Argument ist Murks, und zwar wegen der Begründung: die Menge der 
natürlichen Zahlen ist abzählbar unendlich, aber geordnet, und daher als 
Indexmenge geeignet. Die Menge der rationalen Zahlen ist abzählbar 
unendlich und geordnet, aber es ist nicht möglich, zu irgend einem 
Element dieser Menge einen Vorgänger oder Nachfolger anzugeben.

Abzählbarkeit genügt also nicht; und auch die Anordnung ist lediglich 
notwendige, aber nicht hinreichenee Bedingung.
#6634070
Lesenswert?

Georg schrieb:
> Und wo ist da jetzt der Widerspruch, weshalb du mich als Idioten
> hinstellen willst?

Du hattest behaupter, unendliche Mengen taugten nicht als Indexmengen 
(weil der Speicher nicht unendlich ist), und das ist falsch. Das hatte 
ich auch so geschrieben

Tatsächlich müssen die Indexmengen abzählbar, stark geordnet und nicht 
dicht sein. Deshalb taugen zB rationale Zahlen nicht als Index.

Nichtverzweifelter schrieb:
> Seine übliche Reaktion. Gleich wird eine Juravorlesung daraus.

Nein, es geht um Logik, also so etwas Ähnliches. Verzweifle also nicht 
zu sehr, wenn Du damit nicht klar kommst.
Gast #6634133
Lesenswert?

Percy N. schrieb:

> Tatsächlich müssen die Indexmengen abzählbar, stark geordnet und nicht
> dicht sein. Deshalb taugen zB rationale Zahlen nicht als Index.

Ich würde hier nicht allein auf den Mengenbegriff abstrahieren, sondern 
auch die Ordnungsrelation zwischen den Elementen der Menge betrachten. 
Und das Ganze im Kontext der realen Programmierung sehen.

Bei Menge denken die meisten an eine Wolke wie im Venn-Diagram in der 
die Elemente zweidimensional vor sich hin schweben.
Bei einer Programmiersprache wird aber der Index wie beim 'Text 
schreiben' definiert: die Elemente resp. deren Grenzen werden 
nacheinander niedergeschrieben und so ergibt sich quasi von selbst eine 
'Struktur/Ordnung' der Indexbeschreibung im Programmtext.

Und  sequential wie das 'Schreiben' so das 'Lesen' -> Element nach 
Element mit der Möglichkeit der Neupositionierung des Lesekopfes -> eben 
eine Turingmaschine als klassisches Modell der theoretischen Infomatik.
https://de.wikipedia.org/wiki/Turingmaschine.

So braucht man letzlich als Feldindex ein geschlossenes Intervall, also 
Grenze_rechts und Grenze_links und 'das Ganze' dazwischen.
https://de.wikipedia.org/wiki/Intervall_(Mathematik)

Vielleicht würde auch ein halbgeschlossenes Intervall genügen und die 
Anzahl der Elemente wird lediglich für Runtimechecks benötigt (siehe 
https://man7.org/linux/man-pages/man3/malloc.3.html )

Ob nun die rechte oder linke Intervallgrenze '1' oder '0' ist und ob '1' 
oder '0' überhaupt Elemente des Intervalls sind, ist grad egal.

PS:
Wer sich mal mit (hypothetischen) nichtlinearen Schriften und ihren 
Implikationen auf (menschliche) Deduktion amüsant beschäftigen will, dem 
sei der SF-Film "Arrival" angeraten.

https://youtu.be/Qd8zT1YAUck?t=100
Gast #6634149
Lesenswert?

Valeri D. schrieb:
> Denn, auch wenn man ein Array mit 255 Elementen in
> einer Schleife angeht und dabei auf int achtet, wird man z.B. so was
> schreiben wollen, ...
1
for (int i=0; i<=255; i++)
2
>   {
3
>   }
> , was nicht zu einem Fehler, jedoch wirklich zu einer endlosen Schleife
> würde, weil die Schleife nie verlassen wird. Zu mind. in c bzw. c++.
> Eine Frage in die Runde - wer kann sagen wieso?

Braucht 1 Schritt weiter um falsch zu prüfen, deswegen schreibt bzw. 
empfindet man man als C-Programmierer richtigerweise i < 255

Dass die Null eine Rolle spielt - hat vermutlich auch mit seiner 
mathematischen Eigenschaft als neutrales Element zu tun.
Analogie z.B. Temperatur-Skala.
Auch Countdowns werden bis Null heruntergezählt, nicht bis 1.

Aber die Eigenschaft als Neutrales Element wird es sein, welches der den 
Vorzug erwirkt, denn es ist ja bereits eine Verallgemeinerung, auf die 
man sich verlassen kann.

https://de.wikipedia.org/wiki/Null

Warum aber jetzt 1?

Ich vermute einen gewissermaßen sozialpsychologischen Hintergrund, den 
aus rein statistischer Sicht ist die 1 ziemlich beliebt.

"nobody wants to be a zero" (Lauri Anderson in Home Of The Brave, die 
ersten 5 Minuten  https://www.youtube.com/watch?v=mua8Pr6uRso  )

na, ist schon klar...;)

Zumindest bei den Binärzahlen gibt es beide Zahlen in gleichwertigem 
Gebrauch.
Gast #6634160
Lesenswert?

rbx schrieb:

> Dass die Null eine Rolle spielt - hat vermutlich auch mit seiner
> mathematischen Eigenschaft als neutrales Element zu tun.
> Analogie z.B. Temperatur-Skala.
> Auch Countdowns werden bis Null heruntergezählt, nicht bis 1.

> Warum aber jetzt 1?
>
> Ich vermute einen gewissermaßen sozialpsychologischen Hintergrund, den
> aus rein statistischer Sicht ist die 1 ziemlich beliebt.

Es gibt da einen historischen Kontext in der östlichen Philosophie.
Die Vertreter des Taoismus disputierten mit den Bhuddhisten um den 
Begriff der 'Leere', der bis zu diesem Disput in der Begriffswelt des 
Taos nicht vorkam.

'0' wird eben nicht nur kontextuell als Zahlzeichen benutzt, sondern in 
anderen Zusammenhängen auch als Symbol für 'Nichts' und Lehre.
Ähnliches gilt wohl auch für '1' - das kann Zahlzeichen sein, aber auch 
Ordinalzahl (das 'Erste') und auch Synbel für 'Einheit'.

Aber jetztz nähern wir uns der Kabalistik und Zahlenmystik ...
https://de.wikipedia.org/wiki/Melencolia_I#/media/Datei:Melencolia_I_(Durero).jpg 
(oben rechts)
#6634213
Lesenswert?

Fpgakuechle K. schrieb:
> Ich würde hier nicht allein auf den Mengenbegriff abstrahieren, sondern
> auch die Ordnungsrelation zwischen den Elementen der Menge betrachten.
> Und das Ganze im Kontext der realen Programmierung sehen.
Das kann man so handhaben; hier wurde alkerdings das Kriterium der 
Abzählbarkeit eingeführt, das nurauf Mengen sinnvoll definiert ist.
> [...]
> Ob nun die rechte oder linke Intervallgrenze '1' oder '0' ist und ob '1'
> oder '0' überhaupt Elemente des Intervalls sind, ist grad egal.
Ja, genau darum ging es hier ursprünglich ;-)

Für wesentlich galte ich aber den Umstand, das neben der strengen 
Ordnungsrelation auchcgewährleistet sein muss, dass ein Element, das 
nicht die Intervallgrenze verkörpert, genau einen Vorgänger und genau 
einen Nachfolger hat. (Vorgönger und Nachfolger hattest Du hier sehr zu 
Recht eingeführt.)

[Exkurs]
Wer es ganz schräg haben möchte, kann natürlich auch reelle Zahlen nals 
Indizes verwenden; die Definition der Nachfolger und Vorgänger ergibt 
sich zwanglos,  wenn im Hinblick auf die Ordnungsrelation die als Ints 
oder Cards aufgefassten Bitmuster der prozessorinternen Darstellung der 
Indizes verwendet werden. Ein lustiger Effekt stellt sich dadurch ein, 
dass die Schrittweite der Indizes mit deren Betrag schwankt. Es sollten 
zur Vermeidung von Ambiguitäten ausschließlich normalisierte 
Repräsentationen verwendet werden.

So ließen sich tatsächlich Reals (die im Prozessor ohnehin rational 
approximiert werden) als Index verwenden.

Sinnvoll wäre das allenfalls zur Obfuscation.
Gast #6634333
Lesenswert?

Wie im richtigen Leben.

Die Nullen entweder ignorieren, bei mir fängt JEDE Schleife mit 1 an, 
und auch das Datagridview. Da ist das coole das ich die 0 Spalte immer 
wegblende und da ein Index verstecke. Was den Zugriff auf eine Zelle 
viel einfacher macht.

Witzigerweise ist MS sich selbst nicht einig. Weil Excel fängt bei 1 an.

Und nicht zu vergessen die "Absolute Null". Die muss man in vielen 
Varianten sogar extra abfragen.

Was mich zu den Schluss geführt hat. Auch ein Null ist wichtig, selbst 
wenn es sie gar nicht gibt. ;)
Beitrag #6634374 wurde von einem Moderator gelöscht.
Moderator #6634416
Lesenswert?

Percy N. schrieb:
> Tatsächlich müssen die Indexmengen abzählbar, stark geordnet und nicht
> dicht sein.

Die Abzählbarkeit alleine ist hinreichend (und natürlich auch
notwendig), um eine beliebige Menge als Indexmenge verwenden zu können.
Die von dir genannten zusätzlichen Kriterien ergeben sich direkt aus der
für die Abzählbarkeit geforderten Injektion der Menge in ℕ.

> Deshalb taugen zB rationale Zahlen nicht als Index.

Doch, natürlich taugen sie dafür, dir muss nur bewusst sein, dass es
neben der numerischen Größer-Relation noch weitere Ordnungsrelationen
gibt, sogar unendlich viele.

Ich habe spaßeshalber mal in Haskell einen Indexoperator für rationale
Zahlen definiert. Da die Zahlen vom Typ Rational intern als ein Paar
beliebig großer (nur durch die Speicherkapazität beschränkter)
Integer-Zahlen repräsentiert werden, können damit die Elemente beliebig
großer Datenstrukturen adressiert werden. Um das zu zeigen, habe ich als
Datenstruktur nicht Arrays, sondern Listen gewählt, weil Listen im
Gegensatz zu Arrays keine fixe Länge haben, sondern (zumindest vom
Sprachmodell her) beliebig wachsen und sogar endlos sein können.

Als Anwendungsbeispiel wird in dem Programm die Liste aller Primzahlen
erzeugt und auf diese Liste mit verschiedenen rationalen Indizes
zugegriffen. Dabei ist garantiert, dass jeder rationale Index genau
einer Primzahl und jede Primzahl genau einem rationalen Index zugeordnet
ist.

Der Indexzugriff im !!!-Operator erfolgt folgendermaßen:

1. lege die Liste xs, auf deren Elemente zugegriffen werden soll, über
   die Liste aller rationalen Zahlen (listdOfAllRationals)

2. suche in listdOfAllRationals den Index q

3. gib das entsprechende Element von xs zurück

Falls es irgendwo in einem Paralleluniversum einen Computer mit
unendlich großer Speicherkapazität gibt, wird diese Software ohne
Modifikation (sie muss nur neukompiliert werden) wirklich alle
rationalen Zahlen als Indizes zulassen :)


PS: Das angehängte Programm ist nicht auf Effizienz getrimmt, sondern
stellt lediglich einen Proof-of-Concept dar.
Angehängte Dateien:
#6634430
Lesenswert?

Yalu X. schrieb:
> Die Abzählbarkeit alleine ist hinreichend (und natürlich auch
> notwendig), um eine beliebige Menge als Indexmenge verwenden zu können.
> Die von dir genannten zusätzlichen Kriterien ergeben sich direkt aus der
> für die Abzählbarkeit geforderten Injektion der Menge in ℕ.
>> Deshalb taugen zB rationale Zahlen nicht als Index.
>
> Doch, natürlich taugen sie dafür, dir muss nur bewusst sein, dass es
> neben der numerischen Größer-Relation noch weitere Ordnungsrelationen
> gibt, sogar unendlich viele.

Damit näherst Du Dich meinem Joke-Beispiel mit den reals des Prozessors. 
Sinnvoll handhabbar ist das jeweils nicht.

Was ist der Nachfolger von 1/3, was der Vorgänger? Wenn Du das jeweils 
im Einzelfall fesrlegen willst, wird das Ganze weitgehend sinnlos.
Gast #6634440
Lesenswert?

Die einzige logische Erklärung für die Null ist das Binär-System.

Alle Bits auf 0 = 0 dez.

Also benutzt man die 0 als Index weil man so Speicherplatz spart. 
Ansonsten bräuchtest du für die 16 eine neue Speicherstellen-Potenz.
Gast #6634534
Lesenswert?

Schlaumaier schrieb:
> Die einzige logische Erklärung für die Null ist das Binär-System.
> Alle Bits auf 0 = 0 dez.
> Also benutzt man die 0 als Index weil man so Speicherplatz spart.
> Ansonsten bräuchtest du für die 16 eine neue Speicherstellen-Potenz.

Ich denke, so langsam verstehst Du es. Es hat zwar nichts mit binär zu 
tun (wäre bei dezimal genauso, wenn man nur 10 Symbole hat und nicht 11) 
und hat auch nichts mit Speicherplatz sparen zu tun, aber Du bist auf 
gutem Weg!
Moderator #6634535
Lesenswert?

Percy N. schrieb:
> Damit näherst Du Dich meinem Joke-Beispiel mit den reals des Prozessors.
> Sinnvoll handhabbar ist das jeweils nicht.

Im zweiten Punkt stimme ich dir zu. Ich wollte mit dem Beispiel nur
zeigen, dass es geht, aber nicht, dass es nützt ;-)

Von deinem Vorschlag, Float-Zahlen über deren Bitmuster als Index zu
verwenden, unterscheidet sich mein Vorschlag aber gewaltig.

Meine Methode realisiert mathematisch sauber eine bijektive Abbildung
der Menge der rationalen Zahlen (bzw. einer Teilmenge davon, wenn die
betrachtete Liste nur endlich lang ist) auf die Listenelemente, d.h.
jeder Index ist genau einem Listenelement und jedes Listenelement genau
einem Index zugeordnet, so wie es auch bei der klassischen Indizierung
mit Integer-Zahlen der Fall ist.

Die Abbildung von Float-Zahlen hingegen ist nur injektiv, aber nicht
surjektiv, weil nicht jedes mögliche Bitmuster einer gültigen Float-Zahl
entspricht. Das bedeutet, dass mit dieser Methode einige Array-Elemente
gar nicht erreichbar sind.

Möchte man als Indizes auch Literale verwenden, ist die Abbildung nicht
einmal mehr injektiv, da wegen der endlichen Genauigkeit der internen
Zahlendarstellung verschiedene Literale das gleiche Bitmuster ergeben
können. So würden bspw. a[1.0] und a[1.0000000000000001] auf dasselbe
Array-Element zugreifen, obwohl die beiden als Literal gegebene Indizes
verschieden sind.

Es kann auch der Fall eintreten, dass a[x1] != a[x2], obwohl x1 == x2
ist, nämlich dann, wenn x1 = +0.0 und x2 = -0.0.

Fazit: Unsere lustigen Indexmethoden (mit Float und Rational) sind beide
in der Praxis völlig nutzlos, aber im Gegensatz zu deiner funktioniert
meine wenigstens fehlerfrei ;-)

> Was ist der Nachfolger von 1/3, was der Vorgänger? Wenn Du das jeweils
> im Einzelfall fesrlegen willst, wird das Ganze weitgehend sinnlos.

Der Vorgänger ist -1/3, der Nachfolger -3. Im Anhang findest du eine
Auflistung der ersten 1000 rationalen Zahlen nach dem Ordnungsschema,
wie es in meinem obigen Programm verwendet wird.

Dieses Ordnungsschema geht übergens auf Georg Cantor zurück, der damit
1873 bewies, dass die rationalen Zahlen abzählbar sind.
Angehängte Dateien:
#6634556
Lesenswert?

Yalu X. schrieb:
> Fazit: Unsere lustigen Indexmengen (Float und Rational) sind beide n der
> Praxis völlig nutzlos, aber im Gegensatz zu deiner funktioniert meine
> wenigstens ;-)

Letzteres sehe ich derzeit noch nicht ;-((

Zur erheiternden Abwechslung ein kleines Beispiel aus den wahren Leben, 
Abteilung "Gut gemeint ist halb verdorben":
Als Student hatte ich einen Job in der Bibliothek des Instituts. Im 
dortigen Lesesaal waren auch zahlreiche Loseblattsammlungen aufgestellt, 
die zumeist Gesetze und Verordnungen enthielten. Derartige Sammlungen 
sind genretypisch weder alphabetisch noch chronologisch geordnet, 
sondern nach Sachgebieten, die üblicherweise numerisch verschlüsselt 
werden. Das ist eigrntlich kein Problem; wer auch nur einmal zB einen 
"Schönfelder" in der Hand hatte, findet sich schnell zurecht.

Eine dieser Sammlungen war aber anders aufgebaut: zwar wurden auch hier 
die Sachgebiete numerisch verschlüsselt und auch jeder Schlüssel nur 
einmal vergeben, nur leider waren die einzelnen Dokumente nach der 
"alphabetischen" Reihenfolge der Indexnummern sortiert, also 1, 10, 
100,1000, 1001, ..., 1100, ..., 12, ..., 3589,  ..., 7, ..., 9999.

Mit dieser Ssmmlung hatten die Benutzer regelmäßig Schwierigkeiten; es 
half auch keine Erläuterung, wie etwa "Stellen Sie sich einfach vor 
jeder Zahl eine '0,' vor" oder "ergänzen Sie einfach in Gedanken jede 
Zahl durch anfügen von Nullen auf vier Stellen". Die Lesesaalaufsicht 
durfte regelmäßig für die Benutzer die gesuchte Stelle heraussuchen. Nun 
ja, "iudex non calculat", das mag auch für Studenten gelten.

Yalu X. schrieb:
> Die Abbildung von Float-Zahlen hingegen ist nur injektiv, aber nicht
> surjektiv, weil nicht jedes Bitmuster einer gültigen Float-Zahl
> entspricht. Das bedeutet, dass einige der Array-Elemente mit dieser
> Methode gar nicht erreichbar sind.

Nein, es bedeutet, dass Array-Elemente nur mit solchen Cards adressiert 
werden, deren Bitmuster einem validen Float entspricht. Die Bedingung, 
dass jeweils genau ein Vorgänger und Nachfolger definiert sind, ist 
erfüllt, selbstverständlich mit Ausmahme der Grenzen.
Dass hierbei Speicherlöcher entstehen können, die keine Daten enthalten, 
steht auf einem anderen Blatt. Es verlangt ja auch niemand, dass jedem 
Array-Element ein Wert zugewiesen wird.
Gast #6634576
Lesenswert?

warum bekommen hier eigentlich die Threadstarter alleine schon für ihre 
Frage dislikes?
Die Leute die das machen, müssen doch echte Probleme in ihrem Leben 
haben, oder?
Vermutlich sind das die berühmten 2% der Linux Desktop Benutzer hehe

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren