mikrocontroller.net

Forum: Compiler & IDEs Anzahl der Felder eines struct array


Autor: struct (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir eine struct folgendermaßen definiert:
typedef struct {
   uint16_t id;
   uint16_t mask;
   char msg[8];
   void (*fp)(void);
} CAN_MSG_T;
und eine array davon angelegt
const CAN_MSG_T message[] = {
   { 0x39C , 0x7FF , "\0" , can_rec_mob0 },
   { 0x66E , 0x7FF , "\0" , can_rec_mob1 },
   { 0x30B , 0x7FF , "\0" , can_rec_mob2 }
}
Meine Frage ist nun, woher ich weiß wie groß das Array der Strukt ist??

Kann ich da mit sizeof arbeiten, oder optimiert der Compiler da noch 
dran rum bzw. fügt Leerräume ein, welche das Ergebnis verfälschen 
würden?

Ich hatte an sowas gedacht:
for( i = 0; i < sizeof( message ); ++i )
    ...
}

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sizeof(message) / sizeof(message[0])

ist dein Freund.

Autor: struct (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
THX, aber ich habe mal gelesen, dass der Compiler unter Umständen 
Leerräume zwischen den einzelnen Elementen einfügt. Das würde das 
Ergebnis ja dann verfälschen oder sehe ich da was falsch?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
struct schrieb:
> THX, aber ich habe mal gelesen, dass der Compiler unter Umständen
> Leerräume zwischen den einzelnen Elementen einfügt.

Innerhalb eines structs ist das schon möglich.

> Das würde das
> Ergebnis ja dann verfälschen oder sehe ich da was falsch?

Du siehst das falsch. Falls es da irgendwelche Restriktionen gibt, die 
der Compiler einhalten muss, dann muss er das erledigen, indem er das 
einzelne Array-Element aufbläst. Zwischen 2 Array-Elementen an sich kann 
keine Lücke sein, die nicht durch Vergrößerung der sizeof eines 
einzelnen Array-Elements entsteht. Ansonsten würde die komplette 
Array-Indizierung, die über Pointerarithmetik definiert ist (die 
wiederrum auf sizeof beruht) sofort zusammenbrechen.

Autor: Harri Hirsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
struct schrieb:

> THX, aber ich habe mal gelesen, dass der Compiler unter Umständen
> Leerräume zwischen den einzelnen Elementen einfügt.

Dann hat da entweder jemand ziemlichen Mist geschrieben, oder du 
verwechselst es mit Struktur-Elementen. Array-Elemente liegen immer 
direkt hintereinander.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Darf man fragen, wozu das hier
"\0"
gut sein soll?

Der Compiler schliesst jeden String automatisch mit einem \0 Zeichen ab. 
(OK, eine Ausnahme gibt es. Die trifft hier aber nicht zu)

Autor: struct (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK seh ich ein.
Da hab ich gleich noch mal eine Frage. Ich habe mir nun eine Funktion 
erstellt, welche die Variable message übergeben bekommt. Also,
void funktionsname (CAN_MSG_T *canmsg){
  for (uint8_t mob=0; mob<(sizeof(canmsg)/sizeof(canmsg[0])); mob++ ){
    canmsg[mob].mask = ...;
    ...
  }
}

Ist das so richtig, oder muss es heißen canmsg[mob]->mask wegen dem 
pointer?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
struct schrieb:
> OK seh ich ein.
> Da hab ich gleich noch mal eine Frage. Ich habe mir nun eine Funktion
> erstellt, welche die Variable message übergeben bekommt. Also,
>
>
> void funktionsname (CAN_MSG_T *canmsg){
>   for (uint8_t mob=0; mob<(sizeof(canmsg)/sizeof(canmsg[0])); mob++ ){
>     canmsg[mob].mask = ...;
>     ...
>   }
> }
> 
>
> Ist das so richtig

Nein. Hier ist das falsch.
An dieser Stelle kannst du die Größe des Arrays nicht mehr feststellen.

Die Funktion bekommt nicht das Array übergeben, sondern einen Pointer 
auf den Anfang des Arrays. Aus dem Pointer ist aber nicht mehr ablesbar 
ob
* er überhaupt auf ein Array zeigt
* und wenn ja, wieviele Arrayelemente da vorhanden sind.


Du musst die Arraygröße mitgeben

Wenn du dir da unsicher bist, dann spiel einfach Compiler (denn sizeof 
wird vom Compiler bereits zu einem Zahlenwert ausgewertet)

Wenn du nur das gegeben hast

  void funktionsname (CAN_MSG_T *canmsg){

und zusätzlich auch noch weißt wie groß ein CAN_MSG_T ist, kannst du dir 
dann ausrechnen wie groß 'das übergebene Array' ist? Konkret. In Form 
von Zahlen. Nicht als Formel. Schaffst du es, nur durch betrachten 
dieser einen Zeule mit einem Zahlenwert dafür hochzukommen?

Du kannst es nicht, weil dir Informationen fehlen. Und genausowenig kann 
es der Compiler.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
struct schrieb:
> void funktionsname (CAN_MSG_T *canmsg){
>   for (uint8_t mob=0; mob<(sizeof(canmsg)/sizeof(canmsg[0])); mob++ ){

Das geht so nicht. Du hast von einem Array gesprochen, nicht von einem 
Zeiger. sizeof(canmsg)/sizeof(canmsg[0]) wird dir Unsinn zurückgeben, 
weil du die Größe eines Zeigers durch die Größe einer CAN_MSG_T teils.

>     canmsg[mob].mask = ...;
>     ...
>   }
> }
>
> Ist das so richtig, oder muss es heißen canmsg[mob]->mask wegen dem
> pointer?

Der Punkt ist schon richtig. Der Index-Operator sorgt schon für die 
Dereferenzierung.

Autor: struct (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK danke. Ich habs jetzt wieder als normale globale Variable. Da brauch 
ich der Funktion gar nicht mehr übergeben^^

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
struct schrieb:
> OK danke. Ich habs jetzt wieder als normale globale Variable. Da brauch
> ich der Funktion gar nicht mehr übergeben^^

Feigling.
So wirst du Parameterübergabe nie lernen, wenn du immer gleich auf 
globale Variablen ausweichst.

Autor: struct (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, ich hab das schon verstanden, was ihr mir gesagt habt mit der 
Größe. Es ist aber auch so, dass die struct nur ein einziges mal 
existiert und sowieso global sein muss, da auch eine isr drauf zugreift.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
struct schrieb:
> Naja, ich hab das schon verstanden, was ihr mir gesagt habt mit der
> Größe.

Gut

> Es ist aber auch so, dass die struct nur ein einziges mal
> existiert und sowieso global sein muss, da auch eine isr
> drauf zugreift.

Das hat damit gar nicht mal soviel zu tun. Es ist nur so, dass 
Funktionen universeller verwendbar werden, wenn sie von keinen globalen 
Variablen abhängen. OK, das wird jetzt bei dir nicht die große Rolle 
spielen, von daher ist es ok. Es hat nur so geklungen, als ob du da den 
Weg des geringsten Widerstands gehst :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.