Forum: PC-Programmierung Mehrere Arrays in einer for-Schleife


von Tim (mski)


Lesenswert?

Hi!

Ist es möglich eine for-Schleife für unterschiedliche Arrays zu nutzen?

Stelle es mir in etwas so vor, funktioniert aber nicht.
1
const byte Arr1[]{Val1, Val2};
2
const byte Arr2[]{Val5, Val9, Val10, Val17};
3
...
4
for(int i = 0; Arrayvariable[i]<4; i++){}

Je nach Situation soll die Arrayvariable mit einem der beiden Arrays 
gefüllt werden. Geht's veiellcht irgendwie über Referenzen?


Gruß

: Verschoben durch Admin
von Georg M. (g_m)


Lesenswert?

Tim schrieb:
> Arrayvariable[i]<4

Und was ist mit i?

von Tim (mski)


Lesenswert?

i zählt die Elemente der Arrays durch.

von Georg M. (g_m)


Lesenswert?

Mache es zuerst getrennt mit zwei Schleifen, dann wird man sehen, was du 
überhaupt erreichen möchtest, dann kann man es eventuell mit nur einer 
Schleife realisieren.

von Rolf M. (rmagnus)


Lesenswert?

Tim schrieb:
> Geht's veiellcht irgendwie über Referenzen?

Das hängt davon ab, welche Programmiersprache das sein soll.

von Tim (mski)


Lesenswert?

Oh, natürlich - C++

von Rolf M. (rmagnus)


Lesenswert?

Dann geht das mit einer Referenz auf das Array, aber nur wenn alle 
Arrays gleich lang sind. Besser wäre ein Zeiger auf das erste Element:
1
const byte* Arrayvariable = Arr1;
Da musst du dann aber natürlich auch irgendwie dafür sorgen, dass deine 
Schleife nicht über das Array-Ende hinaus geht.
Warum verwendest du nicht gleich std::array oder std::vector?

von Tim (mski)


Lesenswert?

Leider sind die arrys unterschiedlich lang - zweischen 3 und 11. Aber 
danke schon mal :)

mit Std... kenne ich mich noch nicht so aus :/

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Tim schrieb:
> Hi!
>
> Ist es möglich eine for-Schleife für unterschiedliche Arrays zu nutzen?
>
> Stelle es mir in etwas so vor, funktioniert aber nicht.
>
1
> const byte Arr1[]{Val1, Val2};
2
> const byte Arr2[]{Val5, Val9, Val10, Val17};
3
> ...
4
> for(int i = 0; Arrayvariable[i]<4; i++){}
5
>
>
> Je nach Situation soll die Arrayvariable mit einem der beiden Arrays
> gefüllt werden. Geht's veiellcht irgendwie über Referenzen?

Beschreibe unmissverständlich in Worten was du exakt machen willst, dann 
kann man daraus Code machen, so ist die Beschreibung zu ungenau dafür.

von Daniel A. (daniel-a)


Lesenswert?

Dir muss erst mal klar sein, was du da überhaupt schreibst. Nehmen wir 
erst mal die normale for Schleife:
1
for(int i=0; i<4; i++){
2
}

Die for schleife hat 3 teile. Der erste teil passiert als erstes. Der 
mittlere teil ist die Bedingung, die wird vor jedem Schleifendurchlauf 
überprüft. Der letzte teil wird nach jedem Schleifendurchlauf geprüft.

Das ist das selbe, wie die for schleife oben:
1
{
2
  int i=0;
3
  while(i<4){
4
    // Inhalt
5
    i++; // Ganz am Schluss
6
  }
7
}

Wenn man da schrittweise durchgeht, passiert da dass:
1
int i = 0; // Variable i vom type int wird deklariert, und mit 0 initialisiert
2
i < 4 // i ist 0, 0 < 4 ergibt 1 (also true / wahr), denn 0 ist kleiner als 4.
3
// Hier würde der Schleifen Inhalt kommen
4
i++ // i wird um 1 erhöht. i ist nun 1.
5
i < 4 // i ist 1, 1 < 4 ergibt 1 (also true / wahr), denn 1 ist kleiner als 4.
6
// Hier würde der Schleifen Inhalt kommen
7
i++ // i wird um 1 erhöht. i ist nun 2.
8
i < 4 // i ist 2, 2 < 4 ergibt 1 (also true / wahr), denn 2 ist kleiner als 4.
9
// Hier würde der Schleifen Inhalt kommen
10
i++ // i wird um 1 erhöht. i ist nun 3.
11
i < 4 // i ist 3, 3 < 4 ergibt 1 (also true / wahr), denn 3 ist kleiner als 4.
12
// Hier würde der Schleifen Inhalt kommen
13
i++ // i wird um 1 erhöht. i ist nun 4.
14
i < 4 // i ist 4, 4 < 4 ergibt 0 (also false / falsch), denn 4 ist nicht kleiner als 4.
15
// Die Schleife ist zu ende

Wie dir eventuell auffällt, hat das noch nichts mit Arrays zu tun.
Wenn du sowas hier hast:
1
const byte Arr1[] = {Val1, Val2};
2
int x = Arr1[0];
Dann heisst das Arr1[0] lediglich, bei Arr1, dereferenziere das 0te 
Element.

Oder sowas:
1
const byte Arr1[] = {Val1, Val2};
2
int i = 0;
3
int x = Arr1[i];
Da heisst das Arr1[i] lediglich, bei Arr1, dereferenziere das Element 
mit index i, in dem Beispiel ist i gerade 0.

Wenn du also z.B. sowas hier hast:
1
  const byte Arr1[] = {1,2,3,4};
2
  const byte Arr2[] = {5,6,7,8};
3
  int Arr3[4];
4
  for(int i=0; i<4; i++){
5
    Arr3[i] = Arr1[i] + Arr2[i];
6
  }

Wir nutzen i hier als Index bei Arrays. Aber das ist keine spezielle 
Sache. Nichts, was man lernen müsste. An I, den Arrays, der Schleife, 
und den Array Lookups, ist da nichts spezielles, was nicht aus den 
einzelnen schritten hervorgehen würde.

Es ist nicht schlecht, das grosse ganze im im Auge zu behalten, was man 
tun will. Aber am ende muss man es halt doch ganz mechanistisch auf 
konkrete einzelne Schritte runter brechen. Man braucht beides. Im Grunde 
ist das alles ganz Stumpfsinniges planen.

Hier kannst du damit zuerst mal anfangen, indem du dir überlegst, was 
kommt da an Daten rein, was geht wieder raus, oder was soll es sonst so 
damit machen. Und dann setzt du es um.

: Bearbeitet durch User
von Tim (mski)


Lesenswert?

Tim T. schrieb:
> Beschreibe unmissverständlich in Worten

Konkreter ist es so:
Ich habe zwei Variablen - a und b.
So lange variable b null ist, soll die for-Schleife laufen. In der 
for-Schleife sind vier Arrays, von den drei Konstant da sind, während 
die Schleife läuft. Der vierte Array wechselt, je nach dem, wie Variable 
a gefüllt ist, zwischen 9 weitern Arrays. Sprich: Es wird ein Wert - 
eine Zahl- an a übergeben, bspw. 3. dann soll das Array 3 den Platz des 
Variablen Array in der for-Schleife annehmen. Alles Arrays sind mit 
Elementen gefüllt, unterschiedlich viele und alle sollen über die 
Zählung der Schleife ausgegeben werden.

: Bearbeitet durch User
von Daniel A. (daniel-a)


Lesenswert?

Es gibt Pointer, die können auf ein Element in einem Array zeigen, und 
man kann die ähnlich wie Arrays verwenden.
1
#include <stdio.h>
2
3
int main() {
4
  int x[2];
5
  int y[3];
6
  int* z = 0;
7
  z = x;
8
  z[0] = 1;
9
  z[1] = 2;
10
  z = y; // Das selbe wie  z = y+0;  oder  z = &y[0];  
11
  z[0] = 3;
12
  z[1] = 4;
13
  z[2] = 5;
14
  printf("%d %d %d %d %d\n", x[0], x[1], y[0], y[1], y[2]); // 1 2 3 4 5
15
}

Man kann auch Pointer auf Arrays haben:
1
#include <stdio.h>
2
3
int main() {
4
  int x[2];
5
  int y[3];
6
  int(*z)[] = &x;
7
  (*z)[0] = 1;
8
  (*z)[1] = 2;
9
  z = &y;
10
  (*z)[0] = 3;
11
  (*z)[1] = 4;
12
  (*z)[2] = 5;
13
  printf("%d %d %d %d %d\n", x[0], x[1], y[0], y[1], y[2]); // 1 2 3 4 5
14
}

Oder Arrays von Pointer:
1
  int* z[] = {x,y};

Und dann gibt es noch Pointer auf Pointer. Kann man auch alles beliebig 
kombinieren.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Tim schrieb:
> Tim T. schrieb:
>> Beschreibe unmissverständlich in Worten
>
> Konkreter ist es so:
> Ich habe zwei Variablen - a und b.
> So lange variable b null ist, soll die for-Schleife laufen. In der
> for-Schleife sind vier Arrays, von den drei Konstant da sind, während
> die Schleife läuft. Der vierte Array wechselt, je nach dem, wie Variable
> a gefüllt ist, zwischen 9 weitern Arrays. Sprich: Es wird ein Wert -
> eine Zahl- an a übergeben, bspw. 3. dann soll das Array 3 den Platz des
> Variablen Array in der for-Schleife annehmen. Alles Arrays sind mit
> Elementen gefüllt, unterschiedlich viele und alle sollen über die
> Zählung der Schleife ausgegeben werden.

Das ist zwar immer noch nicht hinreichend konkret, aber was solls.
Nur eine Frage hierzu, wie wird das Ende eines Arrays erkannt?

von Daniel A. (daniel-a)


Lesenswert?

Nie und gar nicht. Du musst immer selbst schauen, dass du nur auf 
Elemente zugreifst, die auch existieren. Da gibt es mehrere 
Möglichkeiten. Man kann sich merken, wie gross das Array ist / das 
irgendwo abspeichern. Oder man kann sich das Ende des Arrays merken.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Daniel A. schrieb:
> Nie und gar nicht. Du musst immer selbst schauen, dass du nur auf
> Elemente zugreifst, die auch existieren. Da gibt es mehrere
> Möglichkeiten. Man kann sich merken, wie gross das Array ist / das
> irgendwo abspeichern. Oder man kann sich das Ende des Arrays merken.

Geh einfach mal davon aus das mir dieser Sachverhalt durchaus klar ist, 
war an den TO gerichtet damit er die eigentliche Aufgabe sieht.

Und üblich sind zwei Vorgehensweisen: 1. Merken der Arraylänge oder 2. 
ein Terminierungszeichen.

: Bearbeitet durch User
von Raoul D. (raoul_d219)


Lesenswert?

Tim T. schrieb:
> Und üblich sind zwei Vorgehensweisen: 1. Merken der Arraylänge oder 2.
> ein Terminierungszeichen.

Oh je: was soll denn bei dem Elementtyp "byte" der Wert des Sentinel 
sein? 0 oder 255? Und wer stellt sicher, dass dieser Wert nicht 
vorkommt. Nein, das ist Bruch. Wenn man so etwas machen will, dann muss 
man einen Typ nehmen, der in seinem Wertebereich einen ungültigen Wert 
(Null-Wert) hat. Bei byte ist das nicht der Fall bzw. möglich, bei dem 
abgeleiteten Typ T* schon (nullptr). Also, entweder macht man sich einen 
entsprechenden domänenspezifischen Datentyp oder man nimmt einen 
additiven Datentyp aus der stdlib wie etwa std::optional<>.

von Rolf M. (rmagnus)


Lesenswert?

Raoul D. schrieb:
> Tim T. schrieb:
>> Und üblich sind zwei Vorgehensweisen: 1. Merken der Arraylänge oder 2.
>> ein Terminierungszeichen.
>
> Oh je: was soll denn bei dem Elementtyp "byte" der Wert des Sentinel
> sein?

Das kommt auf den Anwendungsfall an. Und wenn's keins gibt, lässt sich 
diese Methode nicht anwenden.

> 0 oder 255? Und wer stellt sicher, dass dieser Wert nicht
> vorkommt.

Entweder gibt es in der Anwendung einen Wert, der in den normalen Daten 
ungenutzt ist, dann muss man das nicht sicherstellen, weil es sich 
automatisch ergibt, oder es gibt keinen, dann kann man es so nicht 
machen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Wenn Du tatsächlich in C++ programmierst und nicht nur C-Code mit dem 
C++-Compiler übersetzt, dann solltest Du entweder std::array<> oder 
std::vector<> als allg. Container verwenden, und nicht raw-c-arrays 
einsetzen. Beim dynamischen std::vextor<> fällt dann auch eine 
Ende-Erkennung per Sentinel oder sonst wie weg.

Deine Quell-Container sind dann etwa von Typ std::vector<byte>, und wenn 
Du davon 9 Stück hast, kannst Du die in std::array<std::vector<byte>, 9> 
stecken.

Deine fixen Container dann ebenso in std::array<std::vector<byte>, 3>;

In der Loop benutzt Du dann einfach den a-ten Container.
1
std::array<std::vector<byte>, 9> containers1;
2
std::array<std::vector<byte>, 3> containers2;
3
4
// ...
5
6
uint8_t a = ...;
7
8
for(size_t i = ...) {
9
     // Prüfen, ob i im Indesbereich des Containers ist.
10
     containers1[a][i] .... // das i-te Element des a-ten Containers
11
}

von Sebastian W. (wangnick)


Lesenswert?

Tim schrieb:
> Konkreter ist es so:
> Ich habe zwei Variablen - a und b.
> So lange variable b null ist, soll die for-Schleife laufen. In der
> for-Schleife sind vier Arrays, von den drei Konstant da sind, während
> die Schleife läuft. Der vierte Array wechselt, je nach dem, wie Variable
> a gefüllt ist, zwischen 9 weitern Arrays.

Das ist relativ einfach. Was soll denn ausgegeben werden, wenn die 
Schleifenvariable für einen Array schon "hinter" dem letzten Element 
steht?

LG, Sebastian

von Philipp K. (philipp_k59)


Lesenswert?

Es ist nicht ganz klar was jetzt das Ziel ist, am besten wäre ein 
Beispielcode der wenigstens den Versuch andeutet.

Hört sich an als würde ein multidimensionaler array das ganze besser 
lösen, bzw. sogar ein array mit Arraypointern.

Ich habe mir jetzt beide beschreibungen durchgelesen und es liest sich 
seltsam, als wenn dort noch ein Fehler drin ist.

von Bruno V. (bruno_v)


Lesenswert?

Tim schrieb:
> Ich habe zwei Variablen - a und b.
> So lange variable b null ist, soll die for-Schleife laufen.

while(b==0) oder for(; b==0) oder If(b) {break;}

> In der for-Schleife sind vier Arrays, von den drei Konstant da sind,
Reduzier das im Beispiel auf 1

> [...4te Array: a ist ] bspw. 3. dann soll das Array 3 den Platz des
> Variablen Array in der for-Schleife annehmen.

(Be)schreibe was du erwartest für
Konstantes Array = 1,2. 1.Variables = 3,4,5. 2.Variables = 6,7,8,9.

Einmal mit ä = 1, einmal a=2. (Oder 0, 1)

Wenn zahlen anders sein müssen, änder sie.  Und wer ändert b?

von Tim (mski)


Lesenswert?

Hatte ich nun gelöst. Schleifen waren der falsche Ansatz. Danke dennoch!

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Hatte ich nun gelöst.

Wirklich ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.