Forum: Compiler & IDEs Zugriff und Zuweisung auf ein Array das aus struct besteht


von Hans Schmidt (Gast)


Lesenswert?

Hallo,

probiere gerade meine bisherigen Funktionen ein wenig genereller zu 
gestalten. Habe vier (Luft-)Pumpen mit zugehöriger Sensorik an einem AVR 
hängen, d.h. zu einer Pumpe gehört genau ein Sensor usw. so dass sich 
quasi immer ein zusammenhängendes Konstrukt ergibt wenn Statusänderungen 
anstehen. Daher würde ich gerne über ein array das aus einem struct 
besteht darauf zugreifen um es später auch noch zu verstehen. Denn ein 
"setze an Portx den Pinx = 1" verstehe ich nicht, während hingegen ein 
setze an Portx den Pin kanal_daten[0].on_off_pin (für mich) 
verständlicher ist.
Scheitere aber schon bei der Zuweisung/Befüllung. Was mache ich falsch, 
bzw. wie geht es richtig?

Gruß, Hans
1
#include <stdlib.h>
2
// Anzahl an Kanaelen
3
#define MAX_CH 4
4
// Aufzaehlung fuer die verfuegbaren Kanaele
5
enum nutzbare_kanaele {CH1=1, CH2=2, CH3=3, CH4=4};
6
// structure fuer Infos zum Anschluss der HW
7
struct kanal_info {
8
  enum nutzbare_kanaele nummer;
9
  uint8_t on_off_pin;
10
  uint8_t flowcontrol_pin;
11
  uint8_t pwm_pin;
12
  uint8_t pwm_timer;
13
};
14
// Array mit Infos/Daten fuer die Kanaele erstellen
15
struct kanal_info kanal_daten[MAX_CH];
16
17
// Beginn des Hauptprogrammes
18
int main(void)
19
{
20
  // Kanalinformationen in die Variable schreiben
21
  struct kanal_info kanal_daten[0] = {CH1, PIND7, PINC0, PIND6, OCR0A};
22
  struct kanal_info kanal_daten[1] = {CH2, PIND2, PINC1, PIND5, OCR0B};
23
  struct kanal_info kanal_daten[2] = {CH3, PINC4, PINC2, PIND3, OCR2B};
24
  struct kanal_info kanal_daten[3] = {CH4, PINC5, PINC3, PINB3, OCR2A};
25
  while (1)
26
  {
27
28
  }
29
  // für korrekte Syntax was zurückgeben
30
  return 0;
31
}

von Wilhelm M. (wimalopaan)


Lesenswert?

Du solltest erst mal schauen, wie man einem Array-Element etwas zuweist.

von Wilhelm M. (wimalopaan)


Lesenswert?

Hans Schmidt schrieb:
> // für korrekte Syntax was zurückgeben
>   return 0;

Nicht notwendig: main() ist in verschiedenen Aspekten besonders.

von Oliver S. (oliverso)


Lesenswert?

Hans Schmidt schrieb:
> Scheitere aber schon bei der Zuweisung/Befüllung. Was mache ich falsch

Das sagt dir eigentlich der Compiler.

Schau dir dazu auch mal an, wie OCR0A etc. definiert ist. Das ist kein 
uint8_t.

Oliver

: Bearbeitet durch User
von Hans Schmidt (Gast)


Lesenswert?

Hmmm, stehe leider weiter auf dem Schlauch...
@Wilhelm: na ja, normalerweise schreibe ich so etwas wie 
meinArray[meinIndex] = gewünschterWert
Aber in einer Anleitung hieß es, ich muss immer das struct davor 
schreiben. Eine Alternative wäre es per typedef einen neuen Typen zu 
definieren. Das hatte ich aber nicht gemacht, um immer in Erinnerung zu 
behalten: das ist ein struct.
Zum return Wert: eine (ur-)alte Version eines AVR Compilers hatte das 
mal angemeckert. Gerade ausprobiert und wird aktuell tatsächlich nicht 
angemahnt ==> fliegt demnächst raus.
@Oliver: Bei mir sind die ganzen Pins und Register defines die vom Wert 
her in einen unit8 passen würden.
1
#define OCR0A   _SFR_IO8(0x27)
Ich habe nur keine Ahnung was hinter dem eigentlichen define/dem special 
functions register IO8 steht, evtl. ist da auch ein weiterer Fehler weil 
dies den Wert 0x27=39dez noch einmal "aufbläht"

Bin leider so schlau wie vorher... Könnt ihr mir bitte noch einen Wink 
mit dem Zaunpfahl geben?

von Oliver S. (oliverso)


Lesenswert?

Ich spende mal ein
1
#include <avr/io.h>

Oliver

von Armin J. (arminj)


Lesenswert?

Hier mal ein Beispiel:
1
const struct IRToCommandMappingStruct IRMapping[] ={
2
{COMMAND_BLINK, IR_COMMAND_FLAG_REGULAR, &doLedBlink20times, blink20times },
3
{COMMAND_ON, IR_COMMAND_FLAG_REGULAR, &doLedOn, LEDon }
4
};

von Wilhelm M. (wimalopaan)


Lesenswert?

Hans Schmidt schrieb:
> @Wilhelm: na ja, normalerweise schreibe ich so etwas wie
> meinArray[meinIndex] = gewünschterWert

Und genau das steht bei Dir eben nicht.

Bei Dir steht (in etwa)

datatype meinArray[meinIndex] = gewünschterWert;

von Wilhelm M. (wimalopaan)


Lesenswert?

Hans Schmidt schrieb:
> @Oliver: Bei mir sind die ganzen Pins und Register defines die vom Wert
> her in einen unit8 passen würden.#define OCR0A   _SFR_IO8(0x27)

Dann schau doch mal nach ;-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Armin J. schrieb:
> const struct IRToCommandMappingStruct IRMapping[] ={
> {COMMAND_BLINK, IR_COMMAND_FLAG_REGULAR, &doLedBlink20times,
> blink20times },
> {COMMAND_ON, IR_COMMAND_FLAG_REGULAR, &doLedOn, LEDon }
> };

Und das ist keine Wertzuweisung, so wie er es machen möchte ...

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Und das ist keine Wertzuweisung, so wie er es machen möchte ...

Möchte er das?  Oder macht er das nur, weil er nicht weiß, wie eine 
richtige Initialisierung geht?
Aber gut, auch Zuweisung geht.
1
kanal_daten[0] = (struct kanal_info){CH1, PIND7, PINC0, PIND6, OCR0A};

Wilhelm M. schrieb:
> Hans Schmidt schrieb:
>> // für korrekte Syntax was zurückgeben
>>   return 0;
>
> Nicht notwendig: main() ist in verschiedenen Aspekten besonders.

Eine eher überflüssigen Regel, die man auch nicht unbedingt kennen muss.

von Hans Schmidt (Gast)


Lesenswert?

Hallo,

@Oliver: mein Fehler. Ja, das muss natürlich rein, sonst sind die 
Pindefinitionen nicht dabei. Da habe ich zu viel eingekürzt.
@Armin: danke dir. Da die Zuordnung konstant ist (spiegelt ja die HW 
Anschlüsse wieder), reicht hier in der Tat eine "Konstante" auch aus und 
ist sogar vermutlich die bessere Wahl
@Wilhelm: ja, das weiß ich. Das hatte ich aber wie gesagt bewusst so 
gemacht. Hatte mich an der Stelle an diese Erklärung hier gehalten:
http://c-buch.sommergut.de/Kapitel13/Strukturen.shtml
Abschnitt Arrays aus Strukturen
1
/* nur eine Struktur initialisieren */
2
struct adresse kunden[100]={
3
  {"Enn", "Georg", 236324, 43788}
4
  };
Dort steht grob gesagt "immer struct" davor
Habe zuerst die avr/sfr_defs.h nciht gefunden, die sagt mir
1
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
2
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
3
4
#  if __AVR_ARCH__ >= 100
5
#    define __SFR_OFFSET 0x00
6
#  else
7
#    define __SFR_OFFSET 0x20
8
#  endif
demnach ist das OCR0A:
1
(*(volatile uint8_t *)(0x27 + __SFR_OFFSET))
@Rolf: danke dir

Guten Start in den Tag, Hans

von Rolf M. (rmagnus)


Lesenswert?

Hans Schmidt schrieb:
> Abschnitt Arrays aus Strukturen/* nur eine Struktur initialisieren */
> struct adresse kunden[100]={
>   {"Enn", "Georg", 236324, 43788}
>   };
> Dort steht grob gesagt "immer struct" davor

Nein, es steht genau einmal davor - bei der Definition des Arrays.
Das wäre bei dir der Teil:

Hans Schmidt schrieb:
> // Array mit Infos/Daten fuer die Kanaele erstellen
> struct kanal_info kanal_daten[MAX_CH];

Und danach versuchst du, lauter neue Arrays mit gleichem Namen zu 
definieren,  eins mit 0 Elementen, eins mit einem Element u.s.w.:

>   // Kanalinformationen in die Variable schreiben
>   struct kanal_info kanal_daten[0] = {CH1, PIND7, PINC0, PIND6, OCR0A};
>   struct kanal_info kanal_daten[1] = {CH2, PIND2, PINC1, PIND5, OCR0B};
>   struct kanal_info kanal_daten[2] = {CH3, PINC4, PINC2, PIND3, OCR2B};
>   struct kanal_info kanal_daten[3] = {CH4, PINC5, PINC3, PINB3, OCR2A};

Du musst lernen, was in C die drei Begriffe Definition, Initialisierung 
und Zuweisung bedeuten. Denn das obige Beispiel nutzt eine Definition 
mit Initialisierung. Du nutzt eine Definition ohne Initialisierung, 
dafür machst du nachher Zuweisungen, die du aber so schreibst wie 
Initialisierungen.

Einfach gesagt:
1
Typ Name; // Definition
2
Typ Name = Wert; // Definition mit Initialisierung
3
Name = Wert; // Zuweisung

: Bearbeitet durch User
von Hans Schmidt (Gast)


Lesenswert?

Hallo Rolf,

danke dir für die Klarstellung.
Dann ist das Beipiel in dem von mir gewählten Link "unglücklich", bzw. 
weil immer nur Codeschnipsel da stehen aus dem Zusammenhang gerissen. 
Denn dort gibt es dann doch auch eine Re-Definition, oder? Zuerst 100 
Elemente (0...99) und dann eine Re-Defintion mit Initialisierung. Oder 
kapiere ich es immer noch nicht?
1
struct adresse{
2
  char szName[30];
3
  char szVorname[30];
4
  unsigned long ulTel;
5
  unsigned long ulPlz;
6
  };
7
8
/* Array aus 100 Strukturen vom
9
 * Typ adresse
10
 */
11
struct adresse kunden[100];
12
13
// [...]
14
15
/* nur eine Struktur initialisieren */
16
struct adresse kunden[100]={
17
  {"Enn", "Georg", 236324, 43788}
18
  };

von Rolf M. (rmagnus)


Lesenswert?

Hans Schmidt schrieb:
> Zuerst 100 Elemente (0...99) und dann eine Re-Defintion mit
> Initialisierung. Oder kapiere ich es immer noch nicht?

Im Prinzip ist das richtig. Allerdings darfst du es nicht zweimal 
definieren.  Du müsstes die erste Definition also weglassen.
Hier kommt dann noch eine weitere Sache hinzu: Die Deklaration. Damit 
wird nur der Name und Typ einer Variablen bekannt gemacht, aber sie wird 
noch nicht erstellt.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Eine eher überflüssigen Regel, die man auch nicht unbedingt kennen muss.

Das main() aber 2 (-3) Signaturen hat, sollte man aber schon kennen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Hans Schmidt schrieb:
> Denn dort gibt es dann doch auch eine Re-Definition, oder?

Mache Dir den Unterschied zwischen Deklaration und Definition klar. Ist 
absolut zentral in C/C++. Schaue mal nach ODR (one-definition-rule).
Als Eselsbrücke: für eine Definition benötigt der Compiler irgendwie 
Speicher (für Variable, Funktionskörper, ...), bei einer Deklaration 
wird nur der Name/Typ eines Symbols bekannt gemacht.

von Ralf G. (ralg)


Lesenswert?

Hans Schmidt schrieb:
>   /* nur eine Struktur initialisieren */
>   struct adresse kunden[100]={
>   {"Enn", "Georg", 236324, 43788}
>   };

Rolf M. schrieb:
> Einfach gesagt:
>  Typ Name; // Definition
>  Typ Name = Wert; // Definition mit Initialisierung
>  Name = Wert; // Zuweisung

@Hans
Was du oben machst, ist die "Definition mit Initialisierung". Allerdings 
für das erste Element (Index '0'!!) von 100 Elementen. Aber: das darf 
nur einmal vorkommen. Die Variable "kunden" ist aber vorher schon 
definiert worden. Dir bleibt in dem Fall nur die "Zuweisung":

Rolf M. schrieb:
> Aber gut, auch Zuweisung geht.
1
kunden[99] = (struct adresse){"Enn", "Georg", 236324, 43788}; // bei 100 Elementen ist '99' der letzte Index!

: Bearbeitet durch User
von Hans Schmidt (Gast)


Lesenswert?

Hallo zusammen,

mir bleibt nur über zu sagen: DANKE!

Gruß, Hans

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.