Forum: Mikrocontroller und Digitale Elektronik Ansi-C 4d Array


von Dominic K. (domi1997)


Angehängte Dateien:

Lesenswert?

Guten Tag zusammen
Ich versuche gerade ein 4 dimensionales Array Aufzustellen. Nun will bei 
mir nicht in den Kopf wie ich dies nun darstellen muss.
Ich interpretiere es wie folgt, doch korrigiert mich bitte wenn ich 
falsch liege:

static unsigned char SwitchTimes[20][2][4][2]=
Die 20 steht für die Anzahl Zeilen.
Die Zwei für die Anzahl Spalten.
Die 4 Für die Anzahl Ziffern die in dem Feld sein können.
Die 2te Zwei für die Anzahl Stapel die existieren.

Also wenn ich auf die 10. Zeile in der 2. Spalte die 3. ziffer auf dem 
ersten Stapel will müsste das wie folgt aussehen:

x = SwitchTimes[10][2][3][1];

Doch entweder stimmt dies nicht oder meine Aufstellung der Tabellen 
werte ist falsch. Ich stelle euch meine Definition und Deklaration der 
Tabelle in den Anhang.

von Kirsch (Gast)


Lesenswert?

ob eindimensionel oder mehr dimensionel

die indexis gehen immer von 0 bis n-1

                    |
....................V
x = SwitchTimes[10][2][3][1];

von Erich (Gast)


Lesenswert?

Dominic K. schrieb:
> Ich versuche gerade ein 4 dimensionales Array Aufzustellen.

SwitchTimes[320]
wäre einfacher.

Gruss

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dominic K. schrieb:
> SwitchTimes[20][2][4][2]

Das bedeutet folgende legale Index-Werte:

SwitchTimes[0 - 19][0 - 1][0 - 3][0 - 1]

von 43222342 (Gast)


Lesenswert?

wie wärs mit einem struct das dir das ganze lesbarerer gestaltet

sonst bekommt man schon beim schreiben der eigentlich gewollten 
funktionen einen knoten im kopf

von Dominic K. (domi1997)


Lesenswert?

Die Tabelle soll später für eine Funktion Schaltzeiten für zwei Relais 
zur Verfügung stellen. 20 Zeilen weil ich 20 Schaltpunkte will. 2 
Spalten für ein und Aus Zeit. 4 Werte weil ich Tag, Stunde, Minute und 
Sekunde Speichern will.Und zwei Stapel weil die 2 Relais eigene Zeiten 
haben. Daher denke ich ist eine 4d Tabelle das beste.

von Dominic K. (domi1997)


Lesenswert?

Kirsch schrieb:
> ob eindimensionel oder mehr dimensionel
>
> die indexis gehen immer von 0 bis n-1
>
>                     |
> ....................V
> x = SwitchTimes[10][2][3][1];

Okey das wusste ich noch hatte es aber gerade nicht im Kopf beim 
Beispiel schreiben aber danke

von Dominic K. (domi1997)


Lesenswert?

Hat jemand vlt gerade ein übersichtliches Beispiel einer 4d Tabelle zur 
hand? Am besten eine bei der Alle werte in den eckigen Klammern anderst 
sind um besser zu erkennen was für was steht.

von Kirsch (Gast)


Lesenswert?

Dominic K. schrieb:
> Hat jemand vlt gerade ein übersichtliches Beispiel einer 4d Tabelle zur
> hand? Am besten eine bei der Alle werte in den eckigen Klammern anderst
> sind um besser zu erkennen was für was steht.

Ein N-Dimensonalles Array ist doch nur eine Struktur um Daten zu 
speichen, was die einzelne dimension bedautet ist doch dir selbst 
überlassen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Deklaration und Initialisierung passen nicht zusammen. Gehen wir mal von
der Initialisierung aus:

1
Sie besteht aus Daten für  2   Relais.
2
Für jedes Relais gibt es   2   Blöcke (je einer für Ein- und Auschaltzeiten).
3
Jeder Block besteht aus   20   Zeiten (Schaltpunkten)
4
Jede Zeit besteht aus      4   Werten (Tag, Stunde, Minute und Sekunde)

Genau in dieser Reihenfolge (also vom Groben zum Feinen hin) müssen auch
die Größenangaben in der Deklaration auftauchen:

1
unsigned char SwitchTimes[2][2][20][4]=

Dann fehlt in Zeile 48 noch ein Komma.

Ich würde aber mindestens die Zeiten nicht als Array, sondern als
Struktur deklarieren, bspw. so:

1
struct zeit {
2
  unsigned char tag, stunde, minute, sekunde;
3
};
4
5
struct einaus {
6
  struct zeit ein, aus;
7
};
8
9
#define ANZ_RELAIS 2
10
#define ANZ_SCHALTPUNKTE 20
11
12
struct einaus schaltzeiten[ANZ_RELAIS][ANZ_SCHALTPUNKTE];

von Eric B. (beric)


Lesenswert?

Dominic K. schrieb:
> Die Tabelle soll später für eine Funktion Schaltzeiten für zwei Relais
> zur Verfügung stellen. 20 Zeilen weil ich 20 Schaltpunkte will. 2
> Spalten für ein und Aus Zeit. 4 Werte weil ich Tag, Stunde, Minute und
> Sekunde Speichern will.Und zwei Stapel weil die 2 Relais eigene Zeiten
> haben. Daher denke ich ist eine 4d Tabelle das beste.
1
typedef struct{
2
  uint8_t day;
3
  uint8_t hour;
4
  uint8_t minute;
5
  unit8_t second;
6
} Timestamp;
7
8
#define SUNDAY 0
9
...
10
#define SATURDAY 6
11
12
typedef struct {
13
  Timestamp on;
14
  Timestamp off;
15
} Switchpoint;
16
17
#define NOF_SWITCHPOINTS 20
18
19
Switchpoint relais1[NOF_SWICHTPOINTS];
20
Switchpoint relais2[NOF_SWITCHPOINTS];
21
22
relais1[0].on = {SUNDAY, 0, 15, 0 }; // first switchpoint ON is Sunday 0:15'00"
Sieht für mich besser aus als einen undurchsichtige 4D Tabelle


// Yalu war eine halbe Minute schneller :-D

von Peter D. (peda)


Lesenswert?

Dominic K. schrieb:
> 20 Zeilen weil ich 20 Schaltpunkte will. 2
> Spalten für ein und Aus Zeit. 4 Werte weil ich Tag, Stunde, Minute und
> Sekunde Speichern will.Und zwei Stapel weil die 2 Relais eigene Zeiten
> haben. Daher denke ich ist eine 4d Tabelle das beste.

Bei wären das:
1
uint32_t SwitchTimes[2][40];
Die [2] sind die Relaisnummer.
Die [40] sind die 40 Zeiten, wovon die geraden einschalten und die 
ungeraden aus.
Und uint32_t sind die Sekunden (z.B. seit 2000).

von Eric B. (beric)


Lesenswert?

Übrigens:

Dominic K. schrieb:
> 20 Zeilen weil ich 20 Schaltpunkte will. 2
> Spalten für ein und Aus Zeit.

Das sind dann insgesamt 40 Schaltpunkte: 20x AN, 20x AUS.
Ist das so gewollt?

von Dr. Sommer (Gast)


Lesenswert?

Mal so am Rande - warum muss es ANSI-C sein, eine 29 Jahre alte 
Sprachversion? Für nahezu jede Plattform sollte es mittlerweile einen 
Compiler für C99 oder gar C11 geben.

von 43222342 (Gast)


Lesenswert?

Dominic K. schrieb:
> ie Tabelle soll später für eine Funktion Schaltzeiten für zwei Relais
> zur Verfügung stellen. 20 Zeilen weil ich 20 Schaltpunkte will. 2
> Spalten für ein und Aus Zeit. 4 Werte weil ich Tag, Stunde, Minute und
> Sekunde Speichern will.Und zwei Stapel weil die 2 Relais eigene Zeiten
> haben. Daher denke ich ist eine 4d Tabelle das beste.


wer sagt das da eine 4D tabelle am besten ist?

2D .. ok aber aslles darüber hinaus verwirrt und mach nur knoten im hirn

von 43222342 (Gast)


Lesenswert?

mach das mit den structs und du bist in 2h fertig.

von Dominic K. (domi1997)


Lesenswert?

Dr. Sommer schrieb:
> Mal so am Rande - warum muss es ANSI-C sein, eine 29 Jahre alte
> Sprachversion? Für nahezu jede Plattform sollte es mittlerweile einen
> Compiler für C99 oder gar C11 geben.

Weil ich Ansi-C gelernt habe und dadurch es am besten verstehen werde. 
Und halt weil es sicher auf meinem Mikroprozessor läuft

von Dominic K. (domi1997)


Lesenswert?

> wer sagt das da eine 4D tabelle am besten ist?
>
> 2D .. ok aber aslles darüber hinaus verwirrt und mach nur knoten im hirn

Weil ich dan 2 mal die selbe Funktion in den Code nehmen müsste

von Dirk B. (dirkb2)


Lesenswert?

Dominic K. schrieb:
> Weil ich dan 2 mal die selbe Funktion in den Code nehmen müsste

Wöfür wäre(n) die dann?

von Dominic K. (domi1997)


Lesenswert?

Die Funktion ist ein Algorithmus der eine neue Zeit die neu gespeichert 
wird mit allen bereits gespeicherten Zeiten vergleicht ob diese sich 
nicht irgendwie überschneiden. es handelt sich um ziemlich viel code was 
doppel wäre...

von 43222342 (Gast)


Lesenswert?

?
das musst du mal nächer erklären warum doppelt?
und warum das durchrollen der einträge viel code ist?

Viel code verstehe ich eher was ab 20000zeilen ..

Die sache mit den relais ist eher was auf 1-2 DIN A4 seiten.

von Dominic K. (domi1997)


Lesenswert?

Eric B. schrieb:
>
> #define NOF_SWITCHPOINTS 20
>
> Switchpoint relais1[NOF_SWICHTPOINTS];
> Switchpoint relais2[NOF_SWITCHPOINTS];
>
> relais1[0].on = {SUNDAY, 0, 15, 0 }; // first switchpoint ON is Sunday
> 0:15'00"
> [/c]
> Sieht für mich besser aus als einen undurchsichtige 4D Tabelle

Sieht für interessant aus bin nur gerade nicht sicher wie ich da die 
Werte wieder auslesen kann. Angenommen ich will die Minute von Relais1 
von der 3. Zeit stimmt dan der folgende Code
x = relais1[3].on->2
Das x ist hier nur ein Platzhalter.

von Dominic K. (domi1997)


Lesenswert?

43222342 schrieb:
> ?
> das musst du mal nächer erklären warum doppelt?
> und warum das durchrollen der einträge viel code ist?
>
> Viel code verstehe ich eher was ab 20000zeilen ..
>
> Die sache mit den relais ist eher was auf 1-2 DIN A4 seiten.

Okey dan ist das Einstellungssache. ist natürlich nur ein kleiner 
Teilausschnitt des ganzen. Und mich verwirrt das eher wenn code doppelt 
vorkommt.

von 43222342 (Gast)


Lesenswert?

1
typedef struct{
2
  uint8_t day;
3
  uint8_t hour;
4
  uint8_t minute;
5
  unit8_t second;
6
} Timestamp;
7
8
typedef struct {
9
  Timestamp on;
10
  Timestamp off;
11
} Switchpoint;
12
13
#define NOF_SWITCHPOINTS 20
14
#define NOF_RELAIS       2
15
16
Switchpoint relais[NOF_RELAIS][NOF_SWICHTPOINTS];
17
18
// werte aus Switchpoint 3 
19
// relais 1
20
uint8_t min = relais[0][2].minute ;
21
22
// relais 2
23
uint8_t min = relais[1][2].minute ;


da man aber nur an oder aus braucht...
kann man speicher sparen und das sogar zusammenfassen
1
typedef enum{
2
  RELAIS_OFF,
3
  RELAIS_ON
4
}relais_state_e;
5
6
typedef struct{
7
  uint8_t          day;
8
  uint8_t          hour;
9
  uint8_t          minute;
10
  unit8_t          second;
11
  relais_state_e   state;
12
} Switchpoint;
13
14
#define NOF_SWITCHPOINTS 20
15
#define NOF_RELAIS       2
16
17
Switchpoint relais[NOF_RELAIS][NOF_SWICHTPOINTS];

von Teo D. (teoderix)


Lesenswert?

Yalu X. schrieb:
> Ich würde aber mindestens die Zeiten nicht als Array, sondern als

Intern nur mit Sekunden arbeiten, und nur für das HID aufbereiten.

von 43222342 (Gast)


Lesenswert?

43222342 schrieb:
> Switchpoint relais[NOF_RELAIS][NOF_SWICHTPOINTS];
>
> // werte aus Switchpoint 3
> // relais 1
> uint8_t min = relais[0][2].minute ;
>
> // relais 2
> uint8_t min = relais[1][2].minute ;

korrektur
1
 // on werte aus Switchpoint 3
2
 // relais 1
3
 uint8_t min = relais[0][2].on.minute ;
4
 // relais 2
5
 uint8_t min = relais[1][2].on.minute ;
6
7
 // off werte aus Switchpoint 3
8
 // relais 1
9
 uint8_t min = relais[0][2].off.minute ;
10
 // relais 2
11
 uint8_t min = relais[1][2].off.minute ;

von 43222342 (Gast)


Lesenswert?

Teo D. schrieb:
>> Ich würde aber mindestens die Zeiten nicht als Array, sondern als
>
> Intern nur mit Sekunden arbeiten, und nur für das HID aufbereiten.

macht die sache noch einfacher :-)

von Dominic K. (domi1997)


Lesenswert?

Werde den Code implementieren und ein Test programm schreiben. Bin 
optimistisch das dieser funktioniert. Danke viel mals an alle

von Dominic K. (domi1997)


Lesenswert?

#define NOF_SWITCHPOINTS 20
#define NOF_RELAIS       2
typedef struct{
  unsigned char day;
  unsigned char hour;
  unsigned char minute;
  unsigned char second;
} Timestamp;

typedef struct {
  Timestamp on;
  Timestamp off;
} Switchpoint;
static Switchpoint relais[NOF_RELAIS][NOF_SWITCHPOINTS];

void TS_Setup(void)
{
  unsigned char i;
  while (i<20)
  {
//     relais[0][i].on = {255,255,255,255};
//     relais[1][i].on = {255,255,255,255};
    i++;
  }
  write_zahl(3,3,relais[0][2].on.minute,3,0,0);
}
Irgendwas mach ich noch falsch den Es kommen pro auskommentierte Linie 
ein { Klammer Fehler sobald ich diese normal einsetze.
Und ja ein For wäre besser geeignet gewesen aber ich wollte die Funktion 
nur 1 mal aufrufen und sicher sein das überall 255er drin stehen.

von 43222342 (Gast)


Lesenswert?

memset( relais , 255, (sizeof(Switchpoint)*NOF_SWITCHPOINTS)*NOF_RELAIS 
);

von Kirsch (Gast)


Lesenswert?

Dominic K. schrieb:
> relais[0][i].on = {255,255,255,255};
> //     relais[1][i].on = {255,255,255,255};

Dieser Syntax geht nur bei der Initialisierung einer Struktur/Array, 
aber nicht bei einer späteren Zuweisung.

muss du leider alles einzeln machen
relais[0][i].on[0] = 255;
relais[0][i].on[1] = 255;
relais[0][i].on[2] = 255;
relais[0][i].on[3] = 255;

von 43222342 (Gast)


Lesenswert?

// alle ON einträge mit 0xff
for( i = 0; i< NOF_SWITCHPOINTS ; i++ ){
     memset( &relais[0][i].on , 0xff , sizeof( Timestamp )) ;
}

// alle OFF einträge mit 0
for( i = 0; i< NOF_SWITCHPOINTS ; i++ ){
     memset( &relais[0][i].off , 0 , sizeof( Timestamp )) ;
}

von 43222342 (Gast)


Lesenswert?

43222342 schrieb:
> // alle ON einträge mit 0xff
> for( i = 0; i< NOF_SWITCHPOINTS ; i++ ){
>      memset( &relais[0][i].on , 0xff , sizeof( Timestamp )) ;
> }
>
> // alle OFF einträge mit 0
> for( i = 0; i< NOF_SWITCHPOINTS ; i++ ){
>      memset( &relais[0][i].off , 0 , sizeof( Timestamp )) ;
> }

releais 2 vergessen

// alle ON einträge mit 0xff
for( i = 0; i< NOF_SWITCHPOINTS ; i++ ){
    memset( &relais[0][i].on , 0xff , sizeof( Timestamp )) ;
    memset( &relais[1][i].on , 0xff , sizeof( Timestamp )) ;
}

// alle OFF einträge mit 0
for( i = 0; i< NOF_SWITCHPOINTS ; i++ ){
    memset( &relais[0][i].off , 0 , sizeof( Timestamp )) ;
    memset( &relais[1][i].off , 0 , sizeof( Timestamp )) ;
}


oder bei mehereren relais

for( i = 0; i< NOF_RELAIS ; i++ ){
  for( k = 0; k< NOF_SWITCHPOINTS ; k++ ){
    memset( &relais[i][k].on , 0xff , sizeof( Timestamp )) ;
  }
}

von Dominic K. (domi1997)


Lesenswert?

Die Funktion um alle zu überschreiben geht nach dem includieren der 
string.h library aber der befehl um auf eine einzelne zeit 
einzuschreiben geht nicht:
relais[0][1].on[0] = 255;
Bringt denn error: subscripted value is neither array nor pointer nor 
vector

von 43222342 (Gast)


Lesenswert?

relais[0][1].on.hour = 10;
relais[0][1].on.minute = 30;
relais[0][1].on.second = 00;
relais[0][1].on.day = 0;

von Dominic K. (domi1997)


Lesenswert?

43222342 schrieb:
> relais[0][1].on.hour = 10;
> relais[0][1].on.minute = 30;
> relais[0][1].on.second = 00;
> relais[0][1].on.day = 0;

Okey klar demfall ist die Methode von Kirsch unpassend danke.

von Yalu X. (yalu) (Moderator)


Angehängte Dateien:

Lesenswert?

Dominic K. schrieb:
>      relais[0][i].on = {255,255,255,255};

Das geht nur in C++.

In C (aber nicht in ANSI C) geht es mit Compound-Literals:
1
      relais[0][i].on = (Timestamp){255,255,255,255};

In ANSI-C kannst du wie in deinem ersten Beispiel das gesamte Array
direkt bei seiner Definition initialisieren (s. Anhang).

Da du aber C99-Kommentare (mit //) benutzen kannst, ist dein Compiler
vielleicht gar nicht so altmodisch wie du denkst, so dass du nicht an
die ANSI-Restriktionen (von 1989) gebunden bist.

von 43222342 (Gast)


Lesenswert?

das mit
1
Timestamp var = {0};
geht auch nur bedingt..
bin damit schon auf die nase gefallen.

das funzt erstmal auf den ersten blick
und vereinfacht ein memset()
aber je nach optimierer ist das auch schonmal irgendwo intern verendet

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.