Mehrere Arrays in einer for-Schleife

OP #7485217
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ß

#7485239
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?

Gast #7485257
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.

#7485330
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.

OP #7485335
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.

#7485368
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.

Gast #7485385
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?

Gast #7485393
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.

#7485433
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<>.

#7485440
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.

#7485826
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
}
#7485829
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

#7486330
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.

#7486458
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?

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