Forum: Mikrocontroller und Digitale Elektronik Größe einer beliebigen Reihe, auch unterschiedlich viele Elemente, berechnen.


von Tim (mski)


Lesenswert?

Guten Abend zusammen!

Mit normalen Arrays ist das kein Problem. Leider bekomme ich es nicht 
mit zweidimensionalen hin. Bitte um Hilfe.

Der einzige Code, über den ich öfter gestolpert bin, ist dieser:
1
#define ROW_SIZE(arr, row) (sizeof(arr[row]) / sizeof(arr[row][0]))

Klingt auch logisch. Klappt nur nicht. Bekomme immer die Anzahl der 
Spalten wieder.
1
byte Stunden[2][4] = {
2
  {1, 2, 3, 4},
3
  {5, 6, 7}
4
};

Ich Programmiere mit der Arduino IDE(C++)

Gruß

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

1
#include <Streaming.h> // die Lib findest du selber ;-)
2
Print &cout = Serial; // cout Emulation für "Arme"
3
4
5
template<typename T, size_t N> size_t arrayCount(T(&)[N])
6
{
7
  return N;
8
}
9
10
byte Stunden[2][4] = {
11
  {1, 2, 3, 4},
12
  {5, 6, 7}
13
};
14
15
16
17
void setup() 
18
{
19
  Serial.begin(9600);
20
  cout << F("Start: ") << F(__FILE__) << endl;
21
  cout << F("Zeilen: ") << arrayCount(Stunden) << endl;
22
  cout << F("Spalten: ") << arrayCount(*Stunden) << endl;
23
}
24
25
void loop() 
26
{
27
28
}

von Tim (mski)


Lesenswert?

Danke. Aber leider funktioniert das nicht.

Die Konsole gibt mir jetzt die Anzahl der Reihen und Spalten aus.

Möchte aber die Anzahl der Elemente jeder Reihe. Also für dieses 
Beispiel: row_0 = 4, row_1 = 3.

von Wilhelm M. (wimalopaan)


Lesenswert?

Arduino F. schrieb:
>
1
> template<typename T, size_t N> size_t arrayCount(T(&)[N])
2
> {
3
>   return N;
4
> }
5
> 
6
> byte Stunden[2][4] = {
7
>   {1, 2, 3, 4},
8
>   {5, 6, 7}
9
> };
10
>

Gute Güte, jetzt quälst Du den TO auch noch mit einem Funktionstemplate 
;-)
Dann mache es wenigstens noch constexpr und gibt ihm den Namen 
size(...), damit man wenigstens etwas näher an die StdLibC++ heranrückt. 
Da ich stark vermute, dass er mit avr-g++ arbeitet, und der keine 
StdLibC++ mitbringt, darf man das auch ruhig in den Namensraum std 
packen.

Und das dieses unsäglich byte für vorzeichenlose Ganzzahlen. Nimm doch 
wenigstens uint8_t.

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Danke. Aber leider funktioniert das nicht.
>
> Die Konsole gibt mir jetzt die Anzahl der Reihen und Spalten aus.
>
> Möchte aber die Anzahl der Elemente jeder Reihe. Also für dieses
> Beispiel: row_0 = 4, row_1 = 3.

Jedes Zeilen Array ist gleich lang.
Das hatten wir doch schon in dem anderen Beitrag von Dir. Nichts 
gelernt?

von Peter D. (peda)


Lesenswert?

Es wird immer der maximal nötige Speicherplatz belegt, anders kann der 
Compiler nicht drauf zugreifen.
Wenn Du den Zugriff auf ungültige Elemente verhindern willst, geht das 
z.B. über einen reservierten Wert (0, 0xFF, NAN).
Oder Du definierst eine Struct, wo zusätzlich die Länge mit abgelegt 
wird (Array of Structs).
Wenn die Länge schon zur Compilezeit feststeht, geht auch ein Array von 
Pointern auf Arrays. Kostet natürlich zusätzlichen Speicher für die 
Pointerliste und etwas Laufzeit zum aufdröseln der Pointer.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Peter D. schrieb:
> Wenn Du den Zugriff auf ungültige Elemente verhindern willst, geht das
> z.B. über einen reservierten Wert (0, 0xFF, NAN).

Warum sollen 0x00 oder 0xff reservierte Werte bei einem Byte sein, wobei 
der DT byte bei Arduino ja dasselbe wie uint8_t ist. Weder für byte noch 
für uint8_t gibt es "ungültige" Werte. Dein Ratschlag ist so, wie man 
das Jahr-2000-Problem vielerorten gelöst hat: einfach Mist.

Und NaN hat byte schon mal gar nicht. Das gibt es bei float oder double.

Auch Pointer-Typen (T*) haben einen definitiv ungültigen Wert: nullptr. 
Alle anderen primitiven DT nicht.

Will man so etwas erreich, dann braucht man einen additiven DT wie etwa 
std::optional<>.

von Tim (mski)


Lesenswert?

Wilhelm M. schrieb:

> Jedes Zeilen Array ist gleich lang.
> Das hatten wir doch schon in dem anderen Beitrag von Dir. Nichts
> gelernt?

Kann mich nicht erinnern, schon mal mit 2-D-Arrays gearbeitet zu haben 
:D

: Bearbeitet durch User
von Tim (mski)


Lesenswert?

Peter D. schrieb:
> Es wird immer der maximal nötige Speicherplatz belegt, anders kann der
> Compiler nicht drauf zugreifen.
> Wenn Du den Zugriff auf ungültige Elemente verhindern willst, geht das
> z.B. über einen reservierten Wert (0, 0xFF, NAN).
> Oder Du definierst eine Struct, wo zusätzlich die Länge mit abgelegt
> wird (Array of Structs).
> Wenn die Länge schon zur Compilezeit feststeht, geht auch ein Array von
> Pointern auf Arrays. Kostet natürlich zusätzlichen Speicher für die
> Pointerliste und etwas Laufzeit zum aufdröseln der Pointer.

Ich möchte über eine Funktion alle Arrays über eine for-Schleife 
ausgeben. Mit normalen Arrays klappt das auch wunderbar. Die Größe wird 
dabei bequem über ein Makro ermittelt. Die Größe wird benötigt, damit 
die Zählschleife weiß, wann sie fertig ist.
1
  #define SIZEOF(arr) sizeof(arr) / sizeof(*arr)
2
3
  {OutputArray(Array, SIZEOF(Array));} 
4
5
  void OutputArray(byte Arr[], byte ArrSize)
6
  {     
7
      for(byte i = 0; i < ArrSize; i++)
8
     {
9
      //do something - Arr[i]
10
     }
11
  }

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:

> Ich möchte über eine Funktion alle Arrays über eine for-Schleife
> ausgeben. Mit normalen Arrays klappt das auch wunderbar. Die Größe wird
> dabei bequem über ein Makro ermittelt. Die Größe wird benötigt, damit
> die Zählschleife weiß, wann sie fertig ist.
>
1
>   #define SIZEOF(arr) sizeof(arr) / sizeof(*arr)
2
> 
3
>   {OutputArray(Array, SIZEOF(Array));}
4
> 
5
>   void OutputArray(byte Arr[], byte ArrSize)
6
>   {
7
>       for(byte i = 0; i < ArrSize; i++)
8
>      {
9
>       //do something - Arr[i]
10
>      }
11
>   }
12
>

Hoffentlich weißt Du auch, dass man diese üble Größenberechnung nicht 
innerhalb(!) einer Funktion durchführen darf.

Zudem: werden Deine Arrays nie größer als 256 Elemente?

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Wilhelm M. schrieb:
>
>> Jedes Zeilen Array ist gleich lang.
>> Das hatten wir doch schon in dem anderen Beitrag von Dir. Nichts
>> gelernt?
>
> Kann mich nicht erinnern, schon mal mit 2-D-Arrays gearbeitet zu haben
> :D

Für mich sieht das

Beitrag "Mehrere Arrays in einer for-Schleife"

nach demselben Problem aus. Mag mich aber auch täuschen.

von Tim (mski)


Lesenswert?

Wilhelm M. schrieb:
> Hoffentlich weißt Du auch, dass man diese üble Größenberechnung nicht
> innerhalb(!) einer Funktion durchführen darf.

Wie meinst du das und wieso? Es funktioniert.

> Zudem: werden Deine Arrays nie größer als 256 Elemente?

Das ist mir bewusst. Ich kenne auch die gängigen anderen Datentypen und 
nutze byte, da ich weiß, dass ich an dieser Stelle nicht mehr benötige.

von Tim (mski)


Lesenswert?

Wilhelm M. schrieb:
> nach demselben Problem aus.

Dort ging es um normale Array, was ich auch gelöst hatte. Zudem hatte 
ich mir das dort noch ganz anders vorgestellt.

Nun geht es um 2D-Arrays.

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Wilhelm M. schrieb:
>> Hoffentlich weißt Du auch, dass man diese üble Größenberechnung nicht
>> innerhalb(!) einer Funktion durchführen darf.
>
> Wie meinst du das und wieso? Es funktioniert.

Ja.
Aber nicht mehr, wenn Du die Größenberechnung mittels dieses dummen 
Macros innerhalb der Funktion machst, und auf den zweiter Parameter der 
Funktion verzichtest.
Denn der Array-Bezeichner an der Aufrufstelle zerfällt zu einem Zeiger 
in der Funktion. Ein Zeiger-Typ bei AVR hat 16 Bit. Damit ist also die 
Größe um den Faktor 2 falsch.

>
>> Zudem: werden Deine Arrays nie größer als 256 Elemente?
>
> Das ist mir bewusst. Ich kenne auch die gängigen anderen Datentypen und
> nutze byte, da ich weiß, dass ich an dieser Stelle nicht mehr benötige.

Na dann ... warten wir es ab ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Tim schrieb:
> byte Stunden[2][4] = {
>   {1, 2, 3, 4},
>   {5, 6, 7}
> };

Wenn du ein mit 4 Elementen deklariertes Array nur mit 3 Werten 
initialisierst, wird das Array deswegen nicht kleiner, sondern der nicht 
explizit initialisierte Teil des Arrays wird implizit mit 0 
initialisiert.

Dein Code ist somit äquivalent zu diesem:
1
byte Stunden[2][4] = {
2
  {1, 2, 3, 4},
3
  {5, 6, 7, 0}
4
};

von Harald K. (kirnbichler)


Lesenswert?

Yalu X. schrieb:
> Wenn du ein mit 4 Elementen deklariertes Array nur mit 3 Werten
> initialisierst

Das ist bei eindimensionalen Array übrigens nicht anders:
1
int bla[4] = { 1, 2, 3 };

Dieses Array enthält vier Elemente, auch wenn nur die ersten drei davon 
initialisiert werden.

von Tim (mski)


Lesenswert?

Wilhelm M. schrieb:
> Na dann ... warten wir es ab ;-)

Im Praxistest hats geklappt.

Einen Teil der Arrays hatte ich in einer Switch-Case-Anweisung gepackt. 
Nun wollte ich den Code "optimieren"/verkürzen, indem ich diesen Block 
in ein 2D-Array packe, da man auf diese Weise, die Elemente(Reihen) 
nacheinander ausgeben lassen könnte. Vielleicht ein Irrglaube. Was wäre 
die Alternative?
Für jedes Arrayelement(Reihe) eine Variable deklarieren? Diese dann 
vielleicht auch noch in einen Block packen, zwecks Durchnummerierung?!
Bspw.:

byte Stunden[2][4] = {
   {1, 2, 3, 4},
   {5, 6, 7}
 };

byte row_size_0 = 4;
byte row_size_1 = 3;

von Tim (mski)


Lesenswert?

Yalu X. schrieb:
> Dein Code ist somit äquivalent zu diesem:

Das war mir nicht bewusst. Vielen Dank :)

von Udo S. (urschmitt)


Lesenswert?

Vielleicht erzählst du einfach was für ein Problem du lösen willst statt 
immer nur nach der Lösung für ein Scheibchen deines angedachten 
Lösungswegs zu fragen.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Yalu X. schrieb:
>> Dein Code ist somit äquivalent zu diesem:
>
> Das war mir nicht bewusst. Vielen Dank :)

Stand schon hier:

Beitrag "Re: Größe einer beliebigen Reihe, auch unterschiedlich viele Elemente, berechnen."

von Tim (mski)


Lesenswert?

Udo S. schrieb:
> Vielleicht erzählst du einfach was für ein Problem du lösen willst statt
> immer nur nach der Lösung für ein Scheibchen deiner angedachten Lösung
> zu fragen.

Es geht nicht um eine explizite Anwendung, sondern darum, eine Reihe von 
2D-Array nacheinander ausgeben zu können. Vielleicht verfolge ich ja 
auch den falschen Ansatz...

Es geht darum, wie beim Array, eine Reihe von Werten zu deklarieren - 
53, 102, 162, diese vielleicht noch thematisch zusammenzufassen und 
dann, nach Bedarf, abzurufen.

von Tim (mski)


Lesenswert?

Wilhelm M. schrieb:
> Stand schon hier:

Dann hab ich es dort wohl nicht richtig verstanden.

von Peter D. (peda)


Lesenswert?

Wilhelm M. schrieb:
> Warum sollen 0x00 oder 0xff reservierte Werte bei einem Byte sein

Oh Gott, das war doch nur als allgemeines Beispiel genannt. Natürlich 
muß der Entwickler darauf achten, daß der reservierte Code nicht regulär 
enthalten sein darf.
Und falls es um float Arrays geht, kann man da z.B. NAN oder INFINITY 
zuweisen und testen.

von Tim (mski)


Lesenswert?

Vielleicht sollte ich noch erwähnen, dass ich Anfänger bin und keine 
Profiambitionen habe. Es jedoch möglichst gut machen möchte.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Tim schrieb:
> Vielleicht sollte ich noch erwähnen, dass ich Anfänger bin und keine
> Profiambitionen habe.

Dann schildere dochmal das Problem und zeige nicht, was du dir als 
Lösung vorstellst.

von Tim (mski)


Lesenswert?

Habe ich das Problem nicht bereits geschildert?

Was fehlt dir?

von Wilhelm M. (wimalopaan)


Lesenswert?

Peter D. schrieb:
> Oh Gott, das war doch nur als allgemeines Beispiel genannt.

Du hast es leider nicht verstanden: uint8_t alias byte hat in seinem 
Wertebereich keine "ungültigen" Werte.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Tim schrieb:
> Für jedes Arrayelement(Reihe) eine Variable deklarieren? Diese dann
> vielleicht auch noch in einen Block packen, zwecks Durchnummerierung?!
> Bspw.:
>
> byte Stunden[2][4] = {
>    {1, 2, 3, 4},
>    {5, 6, 7}
>  };
>
> byte row_size_0 = 4;
> byte row_size_1 = 3;

Das ist eine von vielen Möglichkeiten. Statt dir für die Größen jeweils
einen eigenen Variablennamen auszudenken, kannst du sie auch direkt im
Array Stunden unterbringen, bspw. so:
1
struct row {
2
  byte size;
3
  byte elements[4];
4
};
5
6
row Stunden[] = {
7
  {4, {1, 2, 3, 4}},
8
  {3, {5, 6, 7}}
9
};
10
11
const byte NROWS = (sizeof Stunden / sizeof Stunden[0]);

Dann kannst du folgendermaßen über die gewünschten Elemente von Stunden
iterieren:
1
  for (byte i=0; i<NROWS; i++) {
2
    for (byte j=0; j<Stunden[i].size; j++)
3
      do_something_with(Stunden[i].elements[j]);
4
  }

Andere Möglichkeiten wurden in diesem und dem anderen Thread bereits
genannt, bspw. die Markierung des Endes jeder Reihe durch einen
speziellen Wert, den als normales Reihenelement nicht vorkommt.

Welche der vielfältigen Möglichkeiten die geeignetste ist, hängt vom
konkreten Anwendungsfall ab.

: Bearbeitet durch Moderator
von Tim (mski)


Lesenswert?

Tim schrieb:
>> Dein Code ist somit äquivalent zu diesem:

Also ist das eigentlich Platzverschwendung, wenn man kürzere Arrays 
verwendet, als angegeben?! Wenn ich aber eine Liste von 
Zusammengefassten Werten, die der Reihe nach abgerufen werden sollen, 
möchte, ist es ein notwendiges Übel?

Oder ist das einfach nicht relevant?

von Peter D. (peda)


Lesenswert?

Wilhelm M. schrieb:
> Du hast es leider nicht verstanden: uint8_t alias byte hat in seinem
> Wertebereich keine "ungültigen" Werte.

Hat ja auch niemand behauptet.
Nochmal:
"Natürlich muß der Entwickler darauf achten, daß der reservierte Code 
nicht regulär enthalten sein darf."
Wenn aber der gesamte Wertebereich erlaubt sein soll, muß man es eben 
als struct mit extra Längenelement definieren.

von Tim (mski)


Lesenswert?

Yalu X. schrieb:
1
> struct row {
2
>   byte size;
3
>   byte elements[4];
4
> };
5
> row Stunden[] = {
6
>   {4, {1, 2, 3, 4}},
7
>   {3, {5, 6, 7}}
8
> };
9
> const byte NROWS = (sizeof Stunden / sizeof Stunden[0]);
10
> 
11
> Dann kannst du folgendermaßen über die gewünschten Elemente von Stunden
12
> iterieren:
13
>   for (byte i=0; i<NROWS; i++) {
14
>     for (byte j=0; j<Stunden[i].size; j++)
15
>       do_something_with(Stunden[i].elements[j]);
16
>   }
Das sieht sehr gut aus! Zumindest durch meine bescheidenen Augen 
betrachtet :D Arraystructs sind mir bekannt und verstehe diese. Habe 
damit aber tatsächlich noch nicht wirklich gearbeitet. Werde ich später 
mal ausführlich testen. Derzeit hatten mich Arrays sehr begeistert, da 
ich darin viele Möglichkeiten sehen. Was soll ich sagen, bin halt noch 
ein noob.

Vielen Dank!

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Peter D. schrieb:
> Hat ja auch niemand behauptet.
> Nochmal:
> "Natürlich muß der Entwickler darauf achten, daß der reservierte Code
> nicht regulär enthalten sein darf."

Nochmal: wenn ich ein Objekt vom DT byte oder uint8_t habe, wie sehe ich 
ihm allgemein(!) an, dass es ungültig sein soll? Das ist nicht möglich, 
weil diese DT das einfach nicht hergeben. Damit ist es dann unmöglich, 
guten Code zu schreiben, der allgemeingültig ist, etwa als Rückgabewert 
oder auch als Argument einer Funktion. Entweder hat der DT in seinem 
Wertebereich einen ungültigen Wert, der das "Nichts" ausdrückt, wie etwa 
Zeigertypen oder andere UDT, oder man verwendet dafür einen additiven 
DT, wie std::optional<>.

von Harald K. (kirnbichler)


Lesenswert?

Tim schrieb:
> Wenn ich aber eine Liste von
> Zusammengefassten Werten, die der Reihe nach abgerufen werden sollen,
> möchte, ist es ein notwendiges Übel?

Nö. Kann man auch anders machen, aber die Längeninformation muss man 
halt separat transportieren.
1
struct krempel
2
{
3
  int len;
4
  int *data;
5
};
6
7
int x0[] = {1, 3, 5, 7};
8
int x1[] = {1};
9
int x2[] = {2, 7, 56, 12, 1, 78};
10
int x3[] = {2, 3, 4};
11
12
struct krempel y[] =
13
{
14
  {sizeof (x0) / sizeof (x0[0]), x0},
15
  {sizeof (x1) / sizeof (x1[0]), x1},
16
  {sizeof (x2) / sizeof (x2[0]), x2},
17
  {sizeof (x3) / sizeof (x3[0]), x3},
18
};

Das entspricht dem Beispiel von yalu, mit dem Unterschied, daß für jedes 
Teilarray wirklich nur soviel Platz verwendet wird, wie benötigt wird.

Achte bei der Definition auf die leeren eckigen Klammern! In diesem 
Fall, der nur bei einer Dimension von Array angewandt werden kann, 
bestimmt der Compiler die Arraygröße aus der Größe des Initialisierers.

In der Hilfsstruktur (struct krempel) ist die Anzahl der Arrayelemente 
und ein Pointer auf das Array abgelegt, und das Array y besteht --wie 
bei yalu-- aus mehreren dieser Hilfsstrukturen.

Bei dieser Vorgehensweise aber ist es nicht vermeidbar, die einzelnen 
Arrays mit jeweils einem Variablennamen (x0 .. x3) anzulegen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Harald K. schrieb:
> In der Hilfsstruktur (struct krempel) ist die Anzahl der Arrayelemente
> und ein Pointer auf das Array abgelegt, und das Array y besteht --wie
> bei yalu-- aus mehreren dieser Hilfsstrukturen.

Dann wird der TO sicher noch Zeiger auf Stack-Objekte dort ablegen, und 
sich wundern, warum es nicht funktioniert.

Leute, der TO verwendet C++. Ihr bringe ihm gerade C bei.

Gibt es denn in diesem tollen Arduino-Zeug nicht auch so etwas wie einen 
FixedVector<>, den man ggf. aus FixedVector<byte, 10> verwenden kann. 
Also ein Array mit maximal 10 Elementen.

von Tim (mski)


Lesenswert?

Harald K. schrieb:
> {sizeof (x0) / sizeof (x0[0]), x0}

Was spricht, in diesem Fall, gegen meine Variante?

>   #define SIZEOF(arr) sizeof(arr) / sizeof(*arr)
>
>   {OutputArray(Array, SIZEOF(Array));}

Ist das nicht sehr ähnlich?!

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Gute Güte, jetzt quälst Du den TO auch noch mit einem Funktionstemplate
> ;-)

Seit C++17 ist das auch schon in der Standardbibliothek mitgeliefert:

https://en.cppreference.com/w/cpp/iterator/size Overload 3

Man kann also einfach std::size(Stunden) schreiben. Aber das ist jetzt 
hier natürlich nicht die Frage vom OP, vermeidet nur lediglich dieses 
hässliche ROW_SIZE Makro. Und fehlersicherer ist es auch, denn wenn man 
versehentlich nur einen Pointer übergibt, meckert der Compiler, anstatt 
einfach was falsches zurückzugeben.

: Bearbeitet durch User
von Tim (mski)


Lesenswert?

Wilhelm M. schrieb:
> Gibt es denn in diesem tollen Arduino-Zeug nicht auch so etwas wie einen
> FixedVector<>, den man ggf. aus FixedVector<byte, 10> verwenden kann.
> Also ein Array mit maximal 10 Elementen.

Bitte was? :D

von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
> Wilhelm M. schrieb:
>> Gute Güte, jetzt quälst Du den TO auch noch mit einem Funktionstemplate
>> ;-)
>
> Seit C++17 ist das auch schon in der Standardbibliothek mitgeliefert:
>
> https://en.cppreference.com/w/cpp/iterator/size Overload 3

Hatten wir schon:

Beitrag "Re: Größe einer beliebigen Reihe, auch unterschiedlich viele Elemente, berechnen."

Allerdings scheint es hier um avr-g++ zu gehen ...

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Wilhelm M. schrieb:
>> Gibt es denn in diesem tollen Arduino-Zeug nicht auch so etwas wie einen
>> FixedVector<>, den man ggf. aus FixedVector<byte, 10> verwenden kann.
>> Also ein Array mit maximal 10 Elementen.
>
> Bitte was? :D

Ist das AVR-Arduino? Also avr-g++? Oder etwa auf ARM (mit newlib)?

von Wilhelm M. (wimalopaan)


Lesenswert?

Tim schrieb:
> Wilhelm M. schrieb:
>> Gibt es denn in diesem tollen Arduino-Zeug nicht auch so etwas wie einen
>> FixedVector<>, den man ggf. aus FixedVector<byte, 10> verwenden kann.
>> Also ein Array mit maximal 10 Elementen.
>
> Bitte was? :D

Besorge Dir ein C++-Buch oder mach einen Online-Kurs.

von Tim (mski)


Lesenswert?

Wilhelm M. schrieb:
> Besorge Dir ein C++-Buch oder mach einen Online-Kurs.

Kannst du da was empfehlen?

von Harald K. (kirnbichler)


Lesenswert?

Wilhelm M. schrieb:
> Leute, der TO verwendet C++. Ihr bringe ihm gerade C bei.

C-Grundlagenwissen ist nicht verkehrt, um zu verstehen, was einem ein 
C++-Compiler an Arbeit abnimmt (und möglicherweise an Komplexität 
draufschaufelt) - wenn man im Embedded-Bereich unterwegs ist, kann es 
längerfristig besser sein, zu wissen, woraus die bunten Bauklötze sind, 
statt sie nur zusammendrücken zu können.

Die teilweise sehr akademischen Diskussionen, die hier in letzter Zeit 
von einigen Protagonisten geführt wurden, sind jedenfalls auch nicht 
hilfreich.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Tim schrieb:
>> Wilhelm M. schrieb:
>>> Gibt es denn in diesem tollen Arduino-Zeug nicht auch so etwas wie einen
>>> FixedVector<>, den man ggf. aus FixedVector<byte, 10> verwenden kann.
>>> Also ein Array mit maximal 10 Elementen.
>>
>> Bitte was? :D
>
> Besorge Dir ein C++-Buch oder mach einen Online-Kurs.

Der Datentyp FixedVector gibt es IMHO weder in der C++-Standard- noch in
der Arduino-Bibliothek, weswegen man ihn auch in keinem C++-Buch finden
wird.

Natürlich kann man diesen Typ selber schreiben. Er entspräche dann in
etwa diesem Typ

Yalu X. schrieb:
> struct row {
>   byte size;
>   byte elements[4];
> };

nur mit dem Unterschied, dass die Maximalgröße als Template-Argument
übergeben wird, der Zugriff auf die Elemente direkt mit dem []-Operator
erfolgt kann und size automatisch aus der Initialiererliste bestimmt
wird.

Um das zu tun (oder auch nur zu verstehen), sind aber Kenntnisse über

- Templates,

- Operatorüberladung und

- Initialisiererlisten

erforderlich, die der TE, der sich selbst als "Noob" bezeichnet,
definitiv (noch) nicht hat.

Deswegen sollten wir erst einmal versuchen, sein Problem mit den
Sprachelementen zu lösen, die er aus seiner Arduino-Praxis schon kennt.
Den von dir vorgeschlagenen FixedVector kann man danach Schritt für
Schritt darauf aufbauen.

Trotzdem ist es natürlich für einen Arduino-Programmierer kein Fehler,
ein C++-Buch durchzuarbeiten. Konkrete Vorschläge dafür habe ich leider
nicht, Mein letztes C++-Buch ist das von Breymann, wobei das schon ein
ziemlicher Schinken ist. Wie es sich im Vergleich zu anderen Büchern
schlägt, kann ich nicht sagen.

von Veit D. (devil-elec)


Lesenswert?

Tim schrieb:

> Es geht nicht um eine explizite Anwendung, sondern darum, eine Reihe von
> 2D-Array nacheinander ausgeben zu können.

Suchst du sowas? Wenn ja machste dir daraus eine Funktion.
1
int a2D [2][4] {
2
  {1,2,3,4,}, 
3
  {5,6,7,8}
4
};
5
     
6
void setup (void)
7
{
8
  Serial.begin(9600);
9
  Serial.println("\nuC Reset ####");
10
11
  for (auto &row : a2D) {
12
    for (auto &col : row){
13
      Serial.println(col);
14
    }
15
  }
16
  Serial.println();
17
}
18
19
void loop (void)
20
{ 
21
}

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Tim schrieb:
> Die Konsole gibt mir jetzt die Anzahl der Reihen und Spalten aus.

So soll es auch sein!

Tim schrieb:
> Möchte aber die Anzahl der Elemente jeder Reihe. Also für dieses
> Beispiel: row_0 = 4, row_1 = 3.
Wie soll das möglich sein?

Solche Arrays sind "rechteckig"!
Haben keine zackeligen Ränder.


> byte Stunden[2][4]
Ein solches Array hat exakt 2*4=8 Zellen. Das ist genau die Zellenzahl 
die du erzwungen hast. Völlig unabhängig davon, was du dir wünscht oder 
was sich in deiner Fantasie abspielt.

Tim schrieb:
>> Besorge Dir ein C++-Buch oder mach einen Online-Kurs.
> Kannst du da was empfehlen?
z.B. dieses: http://www.cppbuch.de/
Veraltete Versionen gibts gerade deutlich billiger.
Warnung: Arduino wird da drin mit keinem Wort erwähnt.

von Harald K. (kirnbichler)


Lesenswert?

Veit D. schrieb:
> Suchst du sowas?

Nee. Das genau sucht er nicht.
Sondern sowas:
1
int a2D [2][4] {
2
  {0,1,2}, 
3
  {5,6,7,8}
4
};

Und er möchte

0 1 2
5 6 7 8

ausgegeben bekommen.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Harald K. schrieb:
> Sondern sowas:

Dann muss ihm "spezial" Bytes dort einfügen.

So wie es auch hier mit '\0' gemacht wird:
1
char test [50] = "bla bla";

von Harald K. (kirnbichler)


Lesenswert?

Arduino F. schrieb:
> Dann muss ihm "spezial" Bytes dort einfügen.

Die Diskussion dreht sich im Kreis.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Harald K. schrieb:
> dreht sich im Kreis.

Bis es der Letzte verstanden hat.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Der Datentyp FixedVector gibt es IMHO weder in der C++-Standard- noch in
> der Arduino-Bibliothek, weswegen man ihn auch in keinem C++-Buch finden
> wird.

Deswegen habe ich auch Arduino-Zeug geschrieben und nicht StdCppLib. 
Denn es gibt ja hier Leute, die sehr "stolz" auf Arduino sind, und ich 
hätte es für möglich gehalten, dass es da so etwas gibt. Das macht 
nämlich Sinn! So wie auch ein std::array<> (ohne std ;-).

Yalu X. schrieb:
> Um das zu tun (oder auch nur zu verstehen), sind aber Kenntnisse über
>
> - Templates,
>
> - Operatorüberladung und
>
> - Initialisiererlisten
>
> erforderlich, die der TE, der sich selbst als "Noob" bezeichnet,
> definitiv (noch) nicht hat.

Sinnerfassendes Lesen ist schon wichtig: er soll das nicht selbst 
schreiben, sondern nur benutzen, so wie er den restlichen Arduino-Kram 
auch einfach nur benutzt. Ich vermute, er wird auch Serial und String 
benutzen.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Wilhelm M. schrieb:
> die sehr "stolz"

Und du bist ein Nörgler, der zwar die Fähigkeit hat, die Ursache des 
Nörgelns zu beseitigen, aber nicht daran interessiert ist.

Also sowas, wie ein Windbeutel, mit einer mentalen Deformation.
Oder auch: Der typische Arduino Basher.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Sinnerfassendes Lesen ist schon wichtig: er soll das nicht selbst
> schreiben, sondern nur benutzen

Es gibt eine Sache, die noch schwieriger ist als Code zu schreiben:
Ihn zu benutzen, solange er noch gar nicht existiert ;-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Arduino F. schrieb:
> Wilhelm M. schrieb:
>> die sehr "stolz"
>
> Und du bist ein Nörgler,

Wenn Du damit jemanden meinst, der Probleme benennt, dann ja ;-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Wenn ja machste dir daraus eine Funktion.

Das wäre dann ein Funktionstemplate. Und ich denke, das ist noch 
außerhalb seines Horizonts;

von Wilhelm M. (wimalopaan)


Lesenswert?

Harald K. schrieb:
> Die teilweise sehr akademischen Diskussionen, die hier in letzter Zeit
> von einigen Protagonisten geführt wurden, sind jedenfalls auch nicht
> hilfreich.

Damit meinst Du ja mich ;-)
Sicher: Programmieren hat etwas mit Informatik zu tun, und das wiederum 
mit Mathematik, und das ist letztendlich akademisch.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Es gibt eine Sache, die noch schwieriger ist als Code zu schreiben:
> Ihn zu benutzen, solange er noch gar nicht existiert ;-)

Wirklich ;-)
Nun ja, es gibt doch hunderte, wenn nicht x-tausende von Bibliotheken 
für Arduino. Ist da wirklich keine darunter, die so etwas wie ein 
FixedVektor<> anbietet?

von Veit D. (devil-elec)


Lesenswert?

Harald K. schrieb:
> Veit D. schrieb:
>> Suchst du sowas?
>
> Nee. Das genau sucht er nicht.

Dann funktioniert das was Tim eigentlich will mit Mehrdimensionalen 
Arrays nicht. Das was Tim möchte funktioniert nur mit EIN-Dimensionalen 
Arrays. Das ist die aktuelle Situation. Nur dann muss man sich keine 
komplizierten durch die Brust ins Auge Lösungen ausdenken, denn die 
Anzahl der Elemente ist zur Compiletime bekannt. Genau das deckt 
Range-based for loop ab.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Wilhelm M. schrieb:
> Nochmal: wenn ich ein Objekt vom DT byte oder uint8_t habe, wie sehe ich
> ihm allgemein(!) an, dass es ungültig sein soll?

Man kann natürlich alles super eng sehen und alles auf die Goldwaage 
legen, aber man muß nicht.
Ich nehme sehr gern einen Leerstring oder Nullpointer als 
Endekennzeichen eines Arrays oder einer Liste. Rein formal sind das 
natürlich gültige Einträge. Ihre Sonderbedeutung erhalten sie durch den 
Kontext.
Das vermeidet Schusselfehler, wenn ich stattdessen die Länge extra mit 
übergeben würde und sich nachträglich die Länge ändert. Oft fügt man 
Elemente später hinzu oder löscht welche.

Auch kann man Werten außerhalb des Nutzungsbereiches eine 
Sonderbedeutung geben, z.B. in meinem Scheduler:
1
#define MAX_SCHEDULE    30
2
3
enum
4
{
5
  T_FREE = MAX_SCHEDULE,
6
  T_LAST,
7
};

von Wilhelm M. (wimalopaan)


Lesenswert?

Peter D. schrieb:
> Ich nehme sehr gern einen Leerstring oder Nullpointer als
> Endekennzeichen eines Arrays oder einer Liste.

Was soll das denn sein? Einen Leerstring als sentinel? Für ein 
Array-of-byte? Oder noch schlimmer, einen nullptr.

Du meinst wahrscheinlich das Stringendezeichen '\0' als sentinel in 
einem Array von char bzw. byte. Das ist die Konvention (!) für 
C-Strings. Kannst Du aber nicht in einem Array von byte anwenden, wenn 
das numerische Bedeutung (wie bei Arduino als uint8_t) hat.

nullptr oder (void*)0 (aka NULL in C) passt doch vom Dt nur in eine 
Array von Pointern. Und ja, genau das habe ich doch geschrieben: Pointer 
DT wie T* haben einen ungültigen Wert, hier nullptr aka NULL in C

von Peter D. (peda)


Lesenswert?

Ich sehe schon, Du willst mich absichtlich nicht verstehen. Es waren 
wieder nur praktische Beispiele, wie gültige Werte eine Sonderbedeutung 
erhalten können. Diese Beispiele waren nicht konkret auf den Typ "byte" 
bezogen (hab ich auch noch nie verwendet).

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Du meinst wahrscheinlich das Stringendezeichen '\0' als sentinel in
> einem Array von char bzw. byte. Das ist die Konvention (!) für
> C-Strings. Kannst Du aber nicht in einem Array von byte anwenden, wenn
> das numerische Bedeutung (wie bei Arduino als uint8_t) hat.

Das geht schon, wenn man man bereit ist, ein einzelnes Element des
Wertebereichs für das Vorhaben zu opfern. Ob und für welches Element
dies möglich ist, hängt von der Anwendung ab. Gerade bei der
Interpretation von byte bzw. uint8_t als Zahlenwert wird der
Wertebereich oft nicht voll ausgeschöpft, so dass entweder 255 oder 0
problemlos als Endemarkierung verwendet werden kann.

Bei den C-Strings wurde ähnlich verfahren: Eigentlich sollten darin
mindestens alle ASCII erlaubt sein. Da aber das ASCII-Zeichen NUL nur
selten verwendet wird, hat man sich dafür entschieden, dieses dem
zulässigen Wertebereich zu entnehmen und ihm stattdessen die Bedeutung
als Endezeichen zukommen zu lassen.

Entsprechendes gilt auch für den NULL-Pointer als Endemarkierung.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Peter D. schrieb:
> Ich sehe schon, Du willst mich absichtlich nicht verstehen.

Nimm's nicht persönlich. Alle anderen haben dich verstanden :)

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Dann funktioniert das was Tim eigentlich will mit Mehrdimensionalen
> Arrays nicht.

Funktionieren tut es schon.

Man könnte sich vorstellen:

[¢]

template<size_t... L>
struct RowLengths;

template<typename RowLengths>
struct Fluttering { ... };

[/c]

Oder wenn nur eine begrenzte Anzahl von verschiedenen Zeilenlängen 
vorkommt:
1
std::array<std::variant<std::array<byte, 10>, std::array<byte, 19>>, 4> flutter;

Nur: der TO wird es nicht erstellen können bzw. Arduino stellt es nicht 
zur Verfügung bzw. die StdLibC++ ist für avr-g++ nicht vorhanden und 
std::variant<> und std::array<> wird er auch nicht schreiben können.

Gäbe es das oben vorgeschlagene FixedVector<> sähe das schon besser aus. 
Wobei natürlich dabei Speicher "verschwendet" wird.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Das geht schon, wenn man man bereit ist, ein einzelnes Element des
> Wertebereichs für das Vorhaben zu opfern. Ob und für welches Element
> dies möglich ist, hängt von der Anwendung ab. Gerade bei der
> Interpretation von byte bzw. uint8_t als Zahlenwert wird der
> Wertebereich oft nicht voll ausgeschöpft, so dass entweder 255 oder 0
> problemlos als Endemarkierung verwendet werden kann.

Das ist doch jetzt echt nicht Dein Ernst. Das ist wie im letzten 
Jahrtausend, sorry. Und so etwas gibst Du einem Anfänger mir. 
Fahrlässig.

Die durch C-Strings motivierte Ausnahme mit '\0' als Sentinel ist schon 
schlimm genug. Sie wäre nur dann gerechtfertigt, wenn der DT char 
definitiv nur für (ASCII)-Zeichen reserviert wäre. Aber er ist ein 
normaler arithmetischer Typ. Deswegen ist auch das großer Mist.

Zeiger-Typen sind die einzigen primitiven DT, die einen ungültigen Wert 
in ihrem Wertebereich haben. Und die Verwendung (Indirektion) für 
definitiv zu einem Programmabbruch (eingebaute "Assertion"). Das ist gut 
so.

In C++ schreibt man sich dafür einen kleinen UDT, der genau das zum 
Ausdruck bringt, was man will. Von mir aus mit 255 als interne Codierung 
für den ungültigen Wert. Aber dann bitte mit einer Assertion bei der 
Initialisierung und einem Typumwandlungsoperator nach bool.

von Harald K. (kirnbichler)


Lesenswert?

Mir fallen spontan auch andere Begriffe ein als "akademisch".

von Peter D. (peda)


Lesenswert?

Wilhelm M. schrieb:
> Zeiger-Typen sind die einzigen primitiven DT, die einen ungültigen Wert
> in ihrem Wertebereich haben.

Ich hatte mal ein 8051 Programm, was sich merkwürdig verhielt. Beim 
Debuggen bin ich dann an eine Stelle gekommen, wo ein Pointer auf 0 
geprüft wurde. Nun hat der 8051 aber Harward-Architektur, d.h. die XDATA 
Adresse 0x0000 ist gültiger SRAM, die dann der Linker auch brav einer 
Struct zugewiesen hat.
Ich hab dann per Linkeroption den XDATA an Adresse 0x0001 definiert und 
es lief einwandfrei.

von Roland F. (rhf)


Lesenswert?

Hallo,
Harald K. schrieb:
> Mir fallen spontan auch andere Begriffe ein als "akademisch".

Mir auch. :-))

rhf

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Peter D. schrieb:
> Ich hab dann per Linkeroption den XDATA an Adresse 0x0001 definiert und
> es lief einwandfrei.

Vor meinem inneren Auge sehe ich hier schon einige Teilnehmer sich vor 
Entsetzen und Schmerz ueber diesen Frevel in ihrem eigenen Erbrochenen 
waelzen ;-)

scnr,
WK

von Wilhelm M. (wimalopaan)


Lesenswert?

Peter D. schrieb:
> Ich hatte mal ein 8051 Programm, was sich merkwürdig verhielt.

Dann hattest Du einfach einen fehlerhaften Compiler. Denn nullptr bzw. 
NULL ist der definitiv ungültige Zeiger. In Deinem Fall wäre ggf. 
(void*)1 richtig gewesen. Beschwere Dich beim Compiler-Hersteller / 
Projekt.

von Wilhelm M. (wimalopaan)


Lesenswert?

Dergute W. schrieb:
> Vor meinem inneren Auge sehe ich hier schon einige Teilnehmer sich vor
> Entsetzen und Schmerz ueber diesen Frevel in ihrem eigenen Erbrochenen
> waelzen ;-)

Wen meinst Du denn noch außer mir? Wobei ich mich nicht angesprochen 
fühle. Womit Ihr auf die Schnauze fallt, ist mir egal ;-)

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Wilhelm M. schrieb:
> Veit D. schrieb:
>> Dann funktioniert das was Tim eigentlich will mit Mehrdimensionalen
>> Arrays nicht.
>
> Funktionieren tut es schon.

Hallo Wilhelm,

wenn sein 2D Array mit der Anzahl von 5 Elementen definiert ist je 
Zeile, er aber nur 3 Werte reinschreibt zur Initialisierung, dann möchte 
er auch nur diese 3 Werte auslesen und nicht 5. Das sehe ich bei dir 
nicht. Und das geht auch ohne Trickserei nicht.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Wilhelm M. schrieb:
>> Veit D. schrieb:
>>> Dann funktioniert das was Tim eigentlich will mit Mehrdimensionalen
>>> Arrays nicht.
>>
>> Funktionieren tut es schon.
>
> Hallo Wilhelm,
>
> wenn sein 2D Array mit der Anzahl von 5 Elementen definiert ist je
> Zeile, er aber nur 3 Werte reinschreibt zur Initialisierung, dann möchte
> er auch nur diese 3 Werte auslesen und nicht 5. Das sehe ich bei dir
> nicht. Und das geht auch ohne Trickserei nicht.

Welchen meiner Vorschläge meinst Du?

von Veit D. (devil-elec)


Lesenswert?


von Wilhelm M. (wimalopaan)


Lesenswert?


von Veit D. (devil-elec)


Lesenswert?

Hallo Wilhelm,

okay, wir drehen das jetzt rum. Zeige bitte dein Programm für den 
Desktop PC mit Ausgabe, da haben alle die StdLibC++. Bin gespannt ob das 
den Vorgaben vom TO entspricht.

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Hallo Wilhelm,
>
> okay, wir drehen das jetzt rum. Zeige bitte dein Programm für den
> Desktop PC mit Ausgabe, da haben alle die StdLibC++. Bin gespannt ob das
> den Vorgaben vom TO entspricht.

Für ein System mit voller Unterstützung der StdLibC++?

Auf die Schnelle würde ich das vermutlich so machen:
1
template<typename C>
2
concept Container = requires(C c) {
3
    std::begin(c);
4
    std::end(c);
5
};
6
7
template<Container C>
8
std::ostream& operator<<(std::ostream& out, const C& c) {
9
    std::cout << '{';
10
    for(const auto& element: c) {
11
        if (&element != &c[0]) {
12
            out << ", ";
13
        }
14
        out << element;
15
    }
16
    std::cout << '}';
17
    return out;    
18
}
19
20
int main(){
21
    std::vector<std::vector<int>> vv{{
22
        {1}, 
23
        {2, 3}, 
24
        {4, 5, 6}
25
    }};
26
    std::cout << vv << '\n';
27
}

Das ergibt:
1
{{1}, {2, 3}, {4, 5, 6}}

Wie schon vorgeschlagen, könnte man, wenn man z.B. auf Head-Allocation 
verzichten möchte, sich ein Klassen-Template
1
template<typename T, size_t Size = 10>
2
struct FixedVector {
3
   // ...
4
};

was man statt std::vector<> einsetzen könnte:
1
   FixedVector<FixedVector<int>> vv{{
2
        {1}, 
3
        {2, 3}, 
4
        {4, 5, 6}
5
    }};

Wie oben auch schon gesagt, hat das natürlich den Nachteil der 
"Speicherverschwendung".

Wenn man das auch nicht möchte und ggf. bereit ist, Speicherverbrauch 
gegen Laufzeit einzutauschen, dann wäre auch das möglich (s.a. oben 
Fluttering).

Bevor jetzt alle wieder aufschreien: dieser Beitrag war nicht an den TO 
gerichtet! Für den TO hätte ich mir nach wie vor ein FixedVector o.ä. 
aud irgendeiner Arduino-Lib gewünscht.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

Danke für die Demo. Ich habe das natürlich ausprobiert. Eine Frage 
bleibt. Woher kommt die Ausgabe der Allerersten und Allerletzten 
Klammer?

Kommentiere ich
std::cout << '{';
std::cout << '}';
aus werden gar keine Klammern ausgegeben.

Wenn ich den Code lese erwarte ich eigentlich das:
{1}, {2, 3}, {4, 5, 6}
und nicht:
{{1}, {2, 3}, {4, 5, 6}}
Wo liegt der Zauber der Allerersten und Allerletzten Klammer?

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Hallo,
>
> Danke für die Demo. Ich habe das natürlich ausprobiert. Eine Frage
> bleibt. Woher kommt die Ausgabe der Allerersten und Allerletzten
> Klammer?
>
> Kommentiere ich
> std::cout << '{';
> std::cout << '}';
> aus werden gar keine Klammern ausgegeben.

Der op<< wird ja rekursiv verwendet. Er macht immer "außen" um alle 
Elemente der Containers die Klammern.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Die beiden std::cout in operator<<() sollten aber out heißen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Die beiden std::cout in operator<<() sollten aber out heißen.

Ups ;-) Perfekt, danke fürs review!

von Wilhelm M. (wimalopaan)


Lesenswert?

Und noch was, was beim schnellen Schreiben hinten runter gefallen ist: 
die Requirements für das Concept Container waren unvollständig:

Besser:
1
template<typename C>
2
concept Container = requires(C c) {
3
    std::begin(c);
4
    std::end(c);
5
    c[0];
6
};

von Veit D. (devil-elec)


Lesenswert?

Wilhelm M. schrieb:

> Der op<< wird ja rekursiv verwendet. Er macht immer "außen" um alle
> Elemente der Containers die Klammern.

ah ja okay.  ;-)
Danke.

von Wilhelm M. (wimalopaan)


Lesenswert?

Veit D. schrieb:
> Bin gespannt ob das
> den Vorgaben vom TO entspricht.

Werden wir wohl nie erfahren ...

von Tim (mski)


Lesenswert?

Veit D. schrieb:
> Hallo Wilhelm,
>
> okay, wir drehen das jetzt rum. Zeige bitte dein Programm für den
> Desktop PC mit Ausgabe, da haben alle die StdLibC++. Bin gespannt ob das
> den Vorgaben vom TO entspricht.

Hatte es, von Yalu X., gerade ins Programm eingesetzt und werde es 
später testen. Sieht aber erst einmal gut aus.

Bin gespannt :)
1
  struct row
2
  {
3
    byte size;
4
    byte hour[6];
5
  };
6
7
  row hours[12] = //1-12
8
  {
9
    {4, { 62,  63,  64,  65        }}, //eins
10
    {4, { 55,  56,  57,  58        }}, //zwei
11
    {4, { 66,  67,  68,  69        }}, //drei
12
    {4, { 73,  74,  75,  76        }}, //vier
13
    {4, { 51,  52,  53,  54        }}, //fünf
14
    {5, { 83,  84,  85,  86, 87    }}, //sechs
15
    {6, { 88,  89,  90,  91, 92, 93}}, //sieben
16
    {4, { 77,  78,  79,  80        }}, //acht
17
    {4, {103, 104, 105, 106        }}, //neun
18
    {4, {109, 108, 107, 106        }}, //zehn
19
    {3, { 49,  50,  51             }}, //elf
20
    {5, { 94,  95,  96,  97, 98    }}  //zwölf
21
  };
22
23
void OutputArrayHours()
24
{
25
const byte NROWS = (sizeof hours / sizeof hours[0]);
26
27
  for (byte i=0; i < NROWS; i++)
28
  {
29
    for (byte j=0; j < hours[i].size; j++)
30
    {
31
      pixels.setPixelColor(hours[i].hour[j], pixels.Color(COLOR, COLOR, COLOR));
32
      pixels.show();
33
    }
34
  }
35
}

: Bearbeitet durch User
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.