Forum: Mikrocontroller und Digitale Elektronik Probleme mit Struct


von Jens (Gast)


Lesenswert?

Hallo, ich möchte gern ein Struct erzeugen:
in meiner main.c:
1
volatile struct
2
{
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
} U_Bat;
und in meiner main.h:
1
extern volatile struct U_Bat_t;

ich bekomme aber die Warnung:

../main.h:9: warning: useless storage class specifier in empty 
declaration


aber es funktioniert.

Jetzt wüsste ich gern warum die Warnung auftaucht.


Danke
Jens

von jemand (Gast)


Lesenswert?

du kannst ein struct nicht volatile machen.
1
struct
2
{
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
} U_Bat;

von Oliver (Gast)


Lesenswert?

U_Bat
U_Bat_t

Preisfrage: Wo ist der Unterschied?

Oliver

von Jens (Gast)


Lesenswert?

Oliver schrieb:
> U_Bat
> U_Bat_t
>
> Preisfrage: Wo ist der Unterschied?
>
> Oliver

Ich weiss es leider nicht und mein C-Buch schweigt sich darüber auch aus 
:-(

von Hans (Gast)


Lesenswert?

Hier:

Jens schrieb:
> } U_Bat;

und hier:

Jens schrieb:
> extern volatile struct U_Bat_t;

!

von ikarus (Gast)


Lesenswert?

Oliver schrieb:
> U_Bat
> U_Bat_t
>
> Preisfrage: Wo ist der Unterschied?
Das er (Jens) falsch abgetippt hat?

von Jens (Gast)


Lesenswert?

Hab ich leider falsh abgetippt, richtig.

So habe ich leider immer noch die fehlermeldung:

in main.c
1
struct
2
{
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
}U_Bat;

in main.h
1
extern volatile struct U_Bat;

von Jens (Gast)


Lesenswert?

sorry, ich habe eine Warnung, siehe oben

von ikarus (Gast)


Lesenswert?

Jens schrieb:
> sorry, ich habe eine Warnung, siehe oben
Siehe Beitrag "Re: Probleme mit Struct"

von Jens (Gast)


Lesenswert?

Ohne Volatile bleibt die Warnung trotzdem

von Karl H. (kbuchegg)


Lesenswert?

Jens schrieb:

> So habe ich leider immer noch die fehlermeldung:

Du bist auf etwas herein gefallen.
Nämlich das es in C erlaubt ist einen namenlosen struct zu erzeugen.

Das hier

>
1
> extern volatile struct U_Bat;
2
>

geht so nicht.
Denn das U_Bat steht hier syntaktisch an einer Stelle an der der Name 
der struct erwartet wird und nicht der Name einer Variablen.

Hier aber
1
struct
2
{
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
} U_Bat;

steht das U_Bat syntaktisch an der Stelle an der der Name eines 
Variablen vergeben werden kann, die vom vorangegangenen Datentyp ist.

Das ist also so zu lesen
1
struct                   // so sieht die Struktur aus
2
{                        // das ist die Beschreibung
3
  uint16_t ist;          // ihres Aufbaus
4
  uint16_t soll;
5
  uint16_t max;
6
}
7
8
   U_Bat;                // und hier wird eine Variable definiert
9
                         // die genau diese Aufbau hat

Aber: Die struct selber, also die Beschreibung des Aufbaus hat bei dir 
keinen Namen. Und da sie keinen Namen hat, kannst du dich klarerweise an 
anderer Stelle auch nicht darauf beziehen. Es gibt einfach nichts worauf 
du dich beziehen könntest.
1
struct U_Bat_t
2
{
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
} U_Bat;

Jetzt hat die Strukturbeschreibung selber einen Namen. Und zusätzlich 
wird auch gleich noch eine Variable davon definiert. Vorstehends ist 
bedeutungsmässig identisch zu
1
struct U_Bat_t               // so soll eine Variable aussehen
2
{                            // die vom Datentyp struct U_BAt_t ist
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
};
7
8
9
struct U_Bat_t U_Bat;       // und hier ist so eine Varable

und dann kann ich mich klarerweise auch von woanders auf diese Variable 
mittels extern beziehen, weil ich den Datentyp davon benennen kann:
1
extern struct U_Bat_t U_Bat;

ob du die Variablen selbst dann auch noch volatile machst oder nicht, 
ist ein Detail, welches die Variablen betrifft, aber nicht die 
Strukturbeschreibung an sich.
1
struct U_Bat_t               // so soll eine Variable aussehen
2
{                            // die vom Datentyp struct U_BAt_t ist
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
};
7
8
9
volatile struct U_Bat_t U_Bat;       // und hier ist so eine Varable
1
extern volatile struct U_Bat_t U_Bat;

Solange dir hier die syntaktischen Feinheiten noch nicht klar sind, rate 
ich dir, die Kurzfassung 'Strukturbeschriebung und Variablendefinition 
in einem Aufwasch' zu meiden und lieber die explizite Form zu 
bevorzugen:

Also nicht so
1
struct U_Bat_t
2
{
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
} U_Bat;

sondern so
1
struct U_Bat_t               // so soll eine Variable aussehen
2
{                            // die vom Datentyp struct U_BAt_t ist
3
  uint16_t ist;
4
  uint16_t soll;
5
  uint16_t max;
6
};
7
8
9
struct U_Bat_t U_Bat;       // und hier ist so eine Varable

Dann hast du hier eine klarere Trennung zwischen der 
Sturkturbeschreibung an sich (dem Bauplan) und den Variablen (dem Haus, 
welches nach diesem Plan gebaut wird)

von Jens (Gast)


Lesenswert?

Vielen Dank für die Erklärung, ich werd es morgen gleich ausprobieren!

von Jens (Gast)


Lesenswert?

Alles klar, jetzt hab ich begriffen.

Kann mir jemand ein guten C-Buch das sich auch mit AVRs Beschäftigt?
Ich habe z.Zt.:
"Mikrocomputertechnik mit Controllern der Atmel AVR RISC Familie"
und bin nur bedingt zufrieden.



Jens

von Rainer (Gast)


Lesenswert?

Also ich mache das so:

struct {
    volatile unsigned int Stunde;
    volatile unsigned int Minute;
    volatile unsigned int Sekunde;
}Clock


dann:

extern struct {
    volatile unsigned int Stunde;
    volatile unsigned int Minute;
    volatile unsigned int Sekunde;
}Clock

Hab noch nie Probleme damit gehabt.

Viele Grüße
Rainer

von Jens (Gast)


Lesenswert?

Ja, wie gesagt, DAS hat bei mir nicht funktioniert.
Ich verwende das AVR-Studio.



Jens

von Karl H. (kbuchegg)


Lesenswert?

Rainer schrieb:
> Also ich mache das so:
>
> struct {
>     volatile unsigned int Stunde;
>     volatile unsigned int Minute;
>     volatile unsigned int Sekunde;
> }Clock
>
>
> dann:
>
> extern struct {
>     volatile unsigned int Stunde;
>     volatile unsigned int Minute;
>     volatile unsigned int Sekunde;
> }Clock
>
> Hab noch nie Probleme damit gehabt.

Solange du immer 100% perfekt arbeitest und bei einer Strukturänderung 
immer alle Stellen veränderst, kannst du das natürlich machen.
Für alle, die so wie ich, gelegentlich auch schon mal Dinge vergessen, 
ist es aber deutlich einfacher, wenn es im kompletten System nur 1 
Strukturbeschreibung gibt, die überall benutzt wird. Damit kann es dann 
den Fall "Inkonsitente Änderungen" gar nicht geben. Ein Fehler den ich 
aufgrund des Programmaufbaus gar nicht machen kann, ist mir immer noch 
lieber als mich auf mein Gedächtnis verlassen zu müssen. Vor allen 
Dingen, wenn der Preis dafür ein Name im globalen Namensraum ist und 
sonst nichts.


Und schliesslich möchte man dann ja auch mal Struktur-Objekte an 
Funktionen als Argumente übergeben und sei es nur in Form eines Pointers 
darauf.

von Jens (Gast)


Lesenswert?

Um nochmal auf meine Frage zu kommen:
Kann mir jemand ein guten C-Buch das sich auch mit AVRs Beschäftigt?
Ich habe z.Zt.:
"Mikrocomputertechnik mit Controllern der Atmel AVR RISC Familie"
und bin nur bedingt zufrieden.


Jemand n Tip für Mich?


Jens

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Was hat das eine mit dem anderen zu tun? C ist C, und das ist es, ob auf 
irgendwelchen µCs oder einem PC.

Es sind allenfalls zusätzlich Spezialitäten zu betrachten, die manche 
µCs so mit sich bringen (wie der Harvard-Krampf "pgmspace.h" bei den 
AVRs), aber das ändert an der Funktionsweise von C selbst nichts.

von Jens (Gast)


Lesenswert?

OK,
dann formuliere ich meine Frage für dich um:

Kenn jemand ne Alternative zu dem oben genannten Buch, bei dem auch C 
behandelt wird?



Jens

von Karl H. (kbuchegg)


Lesenswert?

Jens schrieb:
> Um nochmal auf meine Frage zu kommen:
> Kann mir jemand ein guten C-Buch das sich auch mit AVRs Beschäftigt?
> Ich habe z.Zt.:
> "Mikrocomputertechnik mit Controllern der Atmel AVR RISC Familie"
> und bin nur bedingt zufrieden.


Wo liegt das Problem?

Die Sache ist die:
Ich kann mir schon vorstellen, dass dieses Buch sich auf die Anwendung 
von C auf AVR konzentriert. So ähnlich wie es auch das Tutorium macht.

Das heißt: allgemeine C-Themen werden stiefmütterlich behandelt, wenn 
überhaupt.

In diesem Fall wäre ein C-Buch angebracht, also ein Machwerk in dem es 
um C geht und um nichts anderes. Der "Kernighan&Ritchie Programmieren in 
C" ist ein immer wieder gern gegebener Buchtip. Arbeitet man von dem das 
erste Drittel/Hälfte auf dem PC durch, hat man einen C-Unterbau auf dem 
dann der µC-spezifische Teil aufsetzen kann ohne dass man ins Schwimmen 
kommt.

von Jens (Gast)


Lesenswert?

Ich habe hier noch die C-Kompaktreferenz Stand 2005 liegen, sollte ich 
mir den Schinken ma antun ;-) ?


Jens

von Karl H. (kbuchegg)


Lesenswert?

Jens schrieb:
> Ich habe hier noch die C-Kompaktreferenz Stand 2005 liegen, sollte ich
> mir den Schinken ma antun ;-) ?

Besser als nichts.
Die Rezessionen auf Amazon sind nicht so schlecht.

Ob du damit klar kommst, kannst nur du wissen.

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.