Ansi-C 4d Array

OP #5335798
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.
Angehängte Dateien:
OP #5335843
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.
Gast #5335976
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.
Moderator #5335984
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];
#5335985
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
#5335990
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).
Gast #5336031
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
Gast #5336115
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.
OP #5336122
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.
OP #5336129
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.
Gast #5336146
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];
Gast #5336168
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 ;
OP #5336234
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.
Gast #5336263
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;
Gast #5336266
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 )) ;
}
Gast #5336276
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 )) ;
  }
}
Moderator #5336304
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.
Angehängte Dateien:
Gast #5337020
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

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