Hi,
ich programmiere einen Atmega in C mit AtmelStudio. beim kompilieren
bekomme ich eine Error-Meldung, die ich nicht weiß wie ich die lösen
kann.
Im header steht:
1
typedef struct {
2
uint8_t size;
3
uint8_t idByte[10];
4
uint8_t ack;
5
} Id;
6
7
Id id;
id ist ja jetzt eigentlich global. im c-file möchte ich dann die
elemente beschreiben
1
id->size = 4;
dabei bekomme ich aber die Fehlermeldung:
request for member 'size' in something not a structure or union.
Was kann bzw. muss ich machen, damit ich die Elemente beschreiben und
lesen kann?
Wenn ich einen Punkt machen möchte, fügt AtmelStudio automatisch einen
Pfeil ein. Ich kann zwar dann das zeichen > mit der Backspace-Taste
löschen und dann steht dort ein punkt, bekomme dann aber trotzdem noch
die selbe Fehlermeldung.
Florian schrieb:> in something not a structure or union
Dann scheint der Compiler an der Stelle den Typ von 'id' nicht zu kennen
Hast Du Deinen Header auch per '#inclue' in Dein C-File eingebunden?
guest schrieb:> Hast Du Deinen Header auch per '#inclue' in Dein C-File eingebunden?
Ja, das habe ich gemacht.
Habe den Fehler gefunden. beim Funktionsaufruf war id nicht typ Id,
sondern uint8.
Trotzdem bekomme ich kein Punkt dazwischen, sondern es wird immer ein
pfeil erzeugt
Florian schrieb:> Trotzdem bekomme ich kein Punkt dazwischen, sondern es wird immer ein> pfeil erzeugt
Dann ist der Typ immer noch nicht 'Id' sondern 'Id*'.
Zeig doch mal den kompletten Code, so ist das doch nur stochern im
Nebel.
Florian schrieb:> guest schrieb:>> Hast Du Deinen Header auch per '#inclue' in Dein C-File eingebunden?>> Ja, das habe ich gemacht.> Habe den Fehler gefunden. beim Funktionsaufruf war id nicht typ Id,> sondern uint8.> Trotzdem bekomme ich kein Punkt dazwischen, sondern es wird immer ein> pfeil erzeugt
Logisch, weil du Funktioen keine struct übergeben kannst, sondern nur
einen Pointer auf eine struct.
Bsp:
Harry L. schrieb:> Logisch, weil du Funktioen keine struct übergeben kannst, sondern nur> einen Pointer auf eine struct.
Das war mal teilweise in den allerersten C Versionen so.
Auch als K&R C bekannt.
Spätestens seit 1989 ist dem nivht mehr so.
Man kann sogar komplettes structs als Rückgabewert einer Funktion
nehmen.
Grundsätzlich in header files nie Objekte erzeugen, nur deren Bauplan
beschreiben.
Also deklarieren, nicht instanziiren. Mach dir den Unterschied klar.
Dirk B. schrieb:> Das war mal teilweise in den allerersten C Versionen so.> Auch als K&R C bekannt.>> Spätestens seit 1989 ist dem nivht mehr so.>> Man kann sogar komplettes structs als Rückgabewert einer Funktion> nehmen.
Man kann nur skalare Datentypen übergeben.
Und das hat sich bei C (ohne ++) seit K&R auch nicht geändert.
Harry L. schrieb:> Man kann nur skalare Datentypen übergeben.
Willst du damit sagen, dass man keine Arrays übergeben kann, oder
bezeichnest du auch Strukuren als "nicht skalar"? Weil Strukturen, um
die es bis jetzt ging, kann man übergeben.
mh schrieb:> Harry L. schrieb:>> Man kann nur skalare Datentypen übergeben.> Willst du damit sagen, dass man keine Arrays übergeben kann, oder
Richtig!
Man kann nur einen Pointer auf ein Array übergeben.
https://de.wikipedia.org/wiki/Skalare_Variable> bezeichnest du auch Strukuren als "nicht skalar"? Weil Strukturen, um> die es bis jetzt ging, kann man übergeben.
Falsch!
Du übergibst einen Pointer auf die Struktur.
Harry L. schrieb:> mh schrieb:>> Harry L. schrieb:>>> Man kann nur skalare Datentypen übergeben.>> Willst du damit sagen, dass man keine Arrays übergeben kann, oder> Richtig!> Man kann nur einen Pointer auf ein Array übergeben.
Oder einen Pointer auf dessen erstes Element.
> https://de.wikipedia.org/wiki/Skalare_Variable>>> bezeichnest du auch Strukuren als "nicht skalar"? Weil Strukturen, um>> die es bis jetzt ging, kann man übergeben.>> Falsch!> Du übergibst einen Pointer auf die Struktur.
Nein. Strukturen können als Parameter an Funktionen übergeben werden.
Sie werden dann, wie skalare Typen auch, per Kopie übergeben.
Arrays können nicht übergeben werden, sondern "zerfallen" in einen
Zeiger auf das erste Element. Indirekt könnte man ein Array übergeben,
wenn man es zu einem Element einer Struktur macht und diese dann
übergibt.
Rolf M. schrieb:> Nein. Strukturen können als Parameter an Funktionen übergeben werden.> Sie werden dann, wie skalare Typen auch, per Kopie übergeben.
Reden wir +ber dieselbe Programmiersprache?
Im Fall von C ist das schlicht falsch.
Harry L. schrieb:> Rolf M. schrieb:>> Nein. Strukturen können als Parameter an Funktionen übergeben werden.>> Sie werden dann, wie skalare Typen auch, per Kopie übergeben.>> Reden wir +ber dieselbe Programmiersprache?> Im Fall von C ist das schlicht falsch.
Ich weiß nicht, über welches C du sprichst, aber meine Aussage gilt für
Standard ISO C. Ich hab auch keine Ahnung, wo du die Idee her hast, das
sei anders.
Arrays zerfallen bei den meisten Verwendungsarten (unter anderem bei
Übergabe an eine Funktion) in Zeiger auf deren erstes Element. Bei
Strukturen gibt es so einen Mechanismus nicht.
Aber mal ein Beispiel.
Was denkst du, passiert bei folgendem Programm? Geht es durch den
Compiler, und wenn ja, was gibt es aus? Probiere es auch mal aus.
m.a wurde also nur innerhalb der Funktion verändert, aber nicht im
Hauptprogramm. Die Übergabe fand also als Kopie (by value) statt, nicht
als Pointer.
Das hat mich jetzt nicht wirklich überrascht.
Florian schrieb:> Was kann bzw. muss ich machen, damit ich die Elemente beschreiben und> lesen kann?
Im Grunde kannst du machen was und wie du willst, denn C läßt eine
Menge schwerverständliches Zeugs zu.
Aber raten würde ich dir dennoch zu einem anderen Stil.
Erstens: vermeide typedef, denn damit definiert man keine Typen, sondern
führt nur eine Umbenennung aus. Normal geht das bei struct's so:
struct NameDesStrukturtyps { InhaltDesStrukturtyps };
Eine blöde Eigentümlichkeit bei C ist, daß du beim Deklarieren von
Variablen dann immer struct davor schreiben mußt. Also
struct MeinTyp MeineVariable;
Eigentlich nur deshalb versuchen die Leute, per typedef oder #define das
hinschreiben müssen von "struct" zu vermeiden.
Zweitens: Typen und Variablen bloß durch eine Großschreibung zu
unterscheiden, empfinde ich als ausgemachten Bockmist. Weitaus
deutlicher ist es, wenn man es durch einen Präfix oder Suffix
voneinander unterscheidet. Beispiele:
Foo foo; // schlecht.
T_foo foo; // besser
Tfoo foo; // besser
foo_t foo; // auch besser
Drittens: Das Dranhängen des Asterisks an den Variablenbezeichner
empfinde ich als üble Zumutung. Schließlich ist es eine Typeigenschaft
und nicht eine Eigenschaft des Variablennamens. Also:
int *blabla; // finde ich miserabel
int* blabla; // ist besser, weil sinnfälliger
Aber da machen die C-Leute genauso wie die Linux/Unix-Leute traditionell
gerne die allerübelsten Schnitzer, z.B. einen führenden Punkt im
Dateinamen als Platz für ein Flag (hidden oder nicht). Was hat ein Flag
in einem Namen zu suchen? Sowas ist eine Obliegenheit des Dateisystems,
aber nicht des Dateinamens.
W.S.
W.S. schrieb:> Aber da machen die C-Leute genauso wie die Linux/Unix-Leute traditionell> gerne die allerübelsten Schnitzer, z.B. einen führenden Punkt im> Dateinamen als Platz für ein Flag (hidden oder nicht).
Es ist eigentlich kein Flag, sondern einfach eine Konvention. Dateien,
deren Namen mit einem Punkt beginnen, werden beim Auflisten ausgelassen.
> Was hat ein Flag in einem Namen zu suchen?
Genauso viel, wie das Flag, das angibt, ob die Datei ausgeführt werden
kann ("blah.exe").
Jemand schrieb:> Miserabel, weil int* a, b; eben keine zwei Pointer deklariert.
Das ist klar, aber das ist einer der vielen Geburtsfehler von C - den
man aber problemlos handhaben kann, indem man Variablen einzeln
deklariert.
W.S.