fangen Arys bei 0 oder 1 an?

Gast #6258178
Lesenswert?

cppbert schrieb:
> Was müsste ein Array mit 2 Feldern denn anders machen um nicht als
> Maritze zu funktionieren?

bei Matlab gibt es Arrays und Matrizen. ich weis deshalb nicht, wann 
eine Matrize und dann ein Array besser ist, aber man kann mit einem 
Array auch eine Matrize abbilden, so geht das z.B. in C, weil es keinen 
speziellen Matrizendatentyp gibt in C wie in Matlab.
Gast #6258489
Lesenswert?

kann man in Hugs ( https://www.haskell.org/hugs/pages/downloading.htm ) 
ausprobieren (Notepad, Datei als beispiel.hs bzw. schaumal.hs 
abspeichern..):
1
schaumal x = [x..100]

Ausgabe:
1
Main> schaumal 1
2
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]
3
Main> schaumal 5
4
[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]
5
Main> schaumal 0
6
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]

Matrizen sind eine Rechenhilfe:
https://de.wikipedia.org/wiki/Matrizenmultiplikation

Ist man näher an der Hardware dran (intel cpu, Dos) dann gilt in den 
automatisierten Bereichen normalerweise 0 als "Wert". Z.B. steht in den 
Registern (z.B.) 0000 und wenn man das logisch verküpft mit einem 
anderen Register, wo z.B. 0001 drin steht, dann ist nicht egal, was in 
den Registern steht.
Gast #6258565
Lesenswert?

Bei Visual-Basic ist es 0.

Ich fange aber aus alter Angewohnheit immer mit 1 an. Was dazu führt das 
ich bei Objekten (der Array auch mit 0 anfängt) immer -1 machen muss.

Mein Tipp. Einige dich mit dir selbst auf eine Regel, und merke dir die 
Ausnahmen, das ist sicherer als wenn dir in Schleifen etc, plötzlich was 
fehlt.


Gruß

  Pucki
Gast #6258657
Lesenswert?

DPA schrieb:
> Wenn man es in c ab 1 statt 0 braucht, gibts da noch so einen netten
> kleinen Hack:int*const array = ((int[]){1,2,3})-1;(Ist zwar eigentlich
> ub)

Undefined Behavior.

Ein Zeiger darf auf Elemente innerhalb des Arrays oder auf die Stelle 
direkt hinter dem Array zeigen.
Dein Zeiger zeigt auf die Stelle vor Beginn des Arrays. Das ist UB und 
nicht erlaubt.
Gast #6258661
Lesenswert?

MaWin schrieb:
> Ein Zeiger darf auf Elemente innerhalb des Arrays oder auf die Stelle
> direkt hinter dem Array zeigen.
> Dein Zeiger zeigt auf die Stelle vor Beginn des Arrays. Das ist UB und
> nicht erlaubt.

Ich code nicht in C.  Ich HASSE die Klammern aus der tiefsten Seele 
meines Herzens. Aber nett so Feinheiten zu wissen. VIELEN DANK

Gruß

   Pucki
Gast #6258736
Lesenswert?

Rolf M. schrieb:
> MaWin schrieb:
>> (Ist zwar eigentlich ub)
>>
>> Undefined Behavior.
>
> Ja genau, ub steht für undefined behavior. :)

Ist mir bekannt. Ich wollte nur nochmal hervorheben, dass dieser "Trick" 
eine sehr schlechte Idee ist. Nur falls jemand nicht weiß, was "ub" ist.

UB darf niemals in einem C-Programm auftreten. Der Compiler darf 
annehmen, dass es niemals auftritt. D.h. er darf dir deine ganzen Arrays 
ersatzlos und kommentarlos rausoptimieren. Oder dir stattdessen ein 
Tetris-Spiel bauen. Oder dir das Haus anzünden. Alles dies erlaubt der 
Standard.
Gast #6259185
Lesenswert?

MaWin schrieb:
> Nur falls jemand nicht weiß, was "ub" ist.

Ich habe das leider noch nicht richtig verstanden :-( Ich habe mir dazu 
auch diesen Artikel angeschaut:

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

Da steht ein Codebeispiel für C:
1
int* p = NULL;
2
int i = *p; // undefiniert

Da sind für mich schon zwei Dinge nicht nachvollziehbar - warum steht 
der Stern bei int* und nicht int *p?

Und ich kann doch einem Integer kein Pointer zuweisen, so wie in der 
zweiten Zeile. Es müsste doch vielmehr lauten:

int i = &p;

Und was genau ist NULL? Das hab ich noch nie gesehen.

Alexander K. schrieb:
> Ich fange aber aus alter Angewohnheit immer mit 1 an. Was dazu führt das
> ich bei Objekten (der Array auch mit 0 anfängt) immer -1 machen muss.

Ist denn das sinnvoll? Angenommen, Du hast z.B. eine Datei, wo Du 
Operationen Millionenfach durchführen musst, weil Du z.B. ganz viele 
Messwerte hast. Und wenn Du dann bei jedem Rechenschritt die -1 
abziehst, bedeutet das doch wieder einen Zusatzaufwand - oder täusche 
ich mich da? Wenn es sich vielleicht um ein paar hundert 
Datenoperationen handelt, kann man das gewiss machen.

Ich werde auch manchmal angemeckert, wenn ich z.B. zu viele 
Typenumwandlungen in ein Programm reintue, weil das immer auch kostbare 
Rechenzeit vergeuden soll - oder ist das in Wirklichkeit nicht so 
wichtig?
Gast #6259209
Lesenswert?

Anfänger schrieb:
> Da sind für mich schon zwei Dinge nicht nachvollziehbar - warum steht
> der Stern bei int* und nicht int *p?

Ja gut. Bevor du dich in UB reinarbeitest, solltest du die Basics von C 
verstehen. Kaufe dir ein Einsteigerbuch. Dort werden alle deine Fragen 
in den ersten Kapiteln erklärt.
Moderator #6259227
Lesenswert?

Anfänger schrieb:
> Da sind für mich schon zwei Dinge nicht nachvollziehbar - warum steht
> der Stern bei int* und nicht int *p?

Du kannst den * auch direkt vor das p schreiben. Manche Leute bevorzugen
die eine, andere die andere Schreibweise. Zwischen beiden Gruppen
herrscht Krieg, so dass es nicht viel bringt, darüber zu diskutieren ;-)

Zumindest in C ist
1
int *p = NULL;

konsequenter. Die andere Schreibweise
1
int* p = NULL;

kam mit C++ auf, wo die Typnotation durch Erweiterungen sowieso an
Konsistenz verlor, so dass es dort jeder so macht wie er lustig ist.

Anfänger schrieb:
> Und ich kann doch einem Integer kein Pointer zuweisen, so wie in der
> zweiten Zeile. Es müsste doch vielmehr lauten:
>
> int i = &p;

Lies mal in deinem C/C++-Buch nach, was die Operatoren * und & genau
tun. Dann wird dir das ziemlich schnell klar werden.

Anfänger schrieb:
> Alexander K. schrieb:
>> Ich fange aber aus alter Angewohnheit immer mit 1 an. Was dazu führt das
>> ich bei Objekten (der Array auch mit 0 anfängt) immer -1 machen muss.
>
> Ist denn das sinnvoll?

Er schrieb ja "aus alter Angewohnheit". Wenn du diesbezüglich keine
alten Angewohnheiten hast, fang bei 0 an zu zählen. Damit hast du es in
der Computerei fast überall leichter (nicht nur bei der Indizierung von
Arrays).

Ein Professor sagte einmal: Ingenieure fangen bei 1 an zu zählen,
Informatiker bei 0.
Gast #6259291
Lesenswert?

Yalu X. schrieb:
> Lies mal in deinem C/C++-Buch nach, was die Operatoren * und & genau
> tun. Dann wird dir das ziemlich schnell klar werden.

Das habe ich schon. Da steht, dass mit int *p auf die Speicherstelle 
zugegriffen wird und int i der Wert, der in der Speicherstelle steht. 
Wenn ich jetzt i einen Wert zuweisen will, dann kriege ich doch mit dem 
und-Operator &p den Wert, der an der Speicherstelle steht und kann die 
dann dem i zuweisen.  Oder habe ich da grade einen Denkfehler?
Moderator #6259335
Lesenswert?

Anfänger schrieb:
> Das habe ich schon. Da steht, dass mit int *p auf die Speicherstelle
> zugegriffen wird und int i der Wert, der in der Speicherstelle steht.

1
int *p;

ist nur die Variablendeklaration bzw. -definition von p, mehr nicht.
Entsprechendes gilt für

1
int i;

> Wenn ich jetzt i einen Wert zuweisen will, dann kriege ich doch mit dem
> und-Operator &p den Wert, der an der Speicherstelle steht und kann die
> dann dem i zuweisen.  Oder habe ich da grade einen Denkfehler?

Das stimmt nicht. Steht das tatsächlich so in deinem Buch? Ich glaube
eher nicht :)

Um auf die Speicherstelle zuzugreifen, auf die p zeigt, nimmt man nicht
&, sondern *, also

1
i = *p;

Man kann nun die Variablendefinition mit einer Initialisierung
verbinden, so dass die Variable gleich bei ihrer Entstehung einen
definierten Wert erhält. Das sieht dann so aus:

1
int i = *p;
Gast #6259502
Lesenswert?

Anfänger schrieb:
> Ich werde auch manchmal angemeckert, wenn ich z.B. zu viele
> Typenumwandlungen in ein Programm reintue, weil das immer auch kostbare
> Rechenzeit vergeuden soll - oder ist das in Wirklichkeit nicht so
> wichtig?

Naja, ich hatt erst unlängst n Fall mit m Excel-Sheet aus staatlicher 
Quelle, da hat der Verfasser das Kunststück fertig gebracht eine 
einfache lineare Funktion in eine Funktion fünften Grades zu pressen und 
die zig tausendfach in unzählige Tabellenseiten zu verteilen. Mein 
angegrauter P4 ist schon gleich nach dem laden eingefroren, unbenutzbar. 
Durch ersetzen der Funktion lief das dann auf der alten Kiste tadellos 
... es kann schon sinnvoll sein sich über die Prozessorlast Gedanken zu 
machen auch wenn das heut nicht so populär ist.
#6259583
Lesenswert?

Gustl B. schrieb:
> Negative Indizes sowie umgekehrte Reihenfolge 7 downto 0 ist natürlich
> auch möglich je nach Sprache.

Bei Python kann man auch negative Indizes verwenden, aber da gibt's 
einfach einen automatischen Wrap-Around. Damit ist a[-1] also einfach 
der letzte Eintrag des Arrays a.

Anfänger schrieb:
> Da sind für mich schon zwei Dinge nicht nachvollziehbar - warum steht
> der Stern bei int* und nicht int *p?

Das ist ganz egal, wo der steht. Du kannst int* p oder int *p oder int*p 
oder int * p schreiben. Das ist alles das gleiche. Sogar
1
int
2
           *
3
       p
wäre das gleiche.

> Und ich kann doch einem Integer kein Pointer zuweisen, so wie in der
> zweiten Zeile.

Wird ja nicht. *p ist eine Dereferenzierung. Es wird das zugewiesen, 
worauf er zeigt.

> Es müsste doch vielmehr lauten:
>
> int i = &p;

Das wiederum würde nicht gehen, denn das wäre die Adresse des Zeigers 
selbst (nicht zu verwechseln mit der Adresse, die er enthält).

> Und was genau ist NULL? Das hab ich noch nie gesehen.

Ein Nullzeiger. Das ist ein Zeiger, der bewusst so gewählt ist, dass er 
auf kein gültiges Objekt zeigt. Deshalb ist auch das Verhalten 
undefiniert. Das Dereferenzieren des Nullzeigers löst selbiges aus.

> Alexander K. schrieb:
>> Ich fange aber aus alter Angewohnheit immer mit 1 an. Was dazu führt das
>> ich bei Objekten (der Array auch mit 0 anfängt) immer -1 machen muss.
>
> Ist denn das sinnvoll?

Meiner Meinung nach nicht, aber nicht primär aus Performance-Gründen, 
sondern weil die Gefahr zu groß ist, es irgendwo zu vergessen.

> Ich werde auch manchmal angemeckert, wenn ich z.B. zu viele
> Typenumwandlungen in ein Programm reintue, weil das immer auch kostbare
> Rechenzeit vergeuden soll - oder ist das in Wirklichkeit nicht so
> wichtig?

Typumwandlungen in C brauchen normalerweise keine signifikante 
Rechenzeit, wenn überhaupt. Aber du solltest dir dennoch sicher sein, 
dass du sie nur machst, wenn du sie auch wirklich brauchst. Einfach, 
weil sie ein sehr großes Potenzial für Fehler haben. Man sollte sich in 
C immer bewusst sein, mit welchem Datentyp man gerade arbeitet und 
warum.

Yalu X. schrieb:
> Ein Professor sagte einmal: Ingenieure fangen bei 1 an zu zählen,
> Informatiker bei 0.

Und was machen Informatik-Ingenieure?
Gast #6259898
Lesenswert?

Rolf M. schrieb:
> Yalu X. schrieb:
>> Ein Professor sagte einmal: Ingenieure fangen bei 1 an zu zählen,
>> Informatiker bei 0.
>
> Und was machen Informatik-Ingenieure?

Informatik = 0
Ingenieure = 1
Informatik-Ingenieure = 0 - 1 = -1

Klarer Fall, die fangen bei -1 an zu zählen!

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