Forum: Mikrocontroller und Digitale Elektronik C-Syntax Fehler


von Peter (Gast)


Lesenswert?

Hallo zusammen,
dieses kleine Programm soll a auf die Uart ausgeben..
macht es auch (Initialisierung usw. vorher bereits abgeschlossen
usw..)
Jetzt meine Frage warum muss ich UDR=transmit_byte im unterprogramm
schreiben und nicht UDR=*transmit_byte da transmit_databyte doch eine
Adresse ist und erst mit *transmit_byte den Inhalt bekomme?

Wer kann mir helfen?
MfG
Peter



int main( void )
{
   transmit_databyte('a');
}


void transmit_databyte(char *transmit_byte)
{
/*Transmit Databyte*/
   for(;;) /*endless loop*/
   {
   /*loop until Bit UDRE is set in Register UCSRA*/
   loop_until_bit_is_set (UCSRA,UDRE);
   /*if Bit UDRE is set that means that the transmit/receive register
is empty*/

   UDR=transmit_byte; /*If transmitdatabyte is empty send Hex Value*/
   }

von Matthias (Gast)


Lesenswert?

Hi

weil

transmit_databyte('a');

nicht die Adresse von 'a' übergibt sondern den Wert von a als
Adresse. Wenn du die Adresse von 'a' übergeben willst mußt du
(&'a') schreiben.

Dann klapts auch mit dem Dereferenzierungsoperator (*).

von Peter (Gast)


Lesenswert?

Hallo Matthias,
danke für Deine Hilfe,
aber was meinst Du damit den Wert von a als Adresse
Was ist das? eine Adresse ist doch ein speicherplatz in dem ein Wert
abgelegt wird oder?

von Matthias (Gast)


Lesenswert?

Hi

'a' wird eben als Adresse interpretiert, also in dem Fall 0x61

Matthias

von Peter (Gast)


Lesenswert?

Was ist dann der Inhlt von a wenn a als adresse interpretiert wird


transmit_databyte('a');
...
...
...
UDR=*transmit_byte;

Danke endlich mal einer der konkrete Aussagen macht...

Peter

von Peter (Gast)


Lesenswert?

Was steht dann im UDR?

von Peter (Gast)


Lesenswert?

Hallo Matthias,
Zitat von Dir..

Wenn du die Adresse von 'a' übergeben willst mußt du
(&'a') schreiben.

Dann klapts auch mit dem Dereferenzierungsoperator (*).


Ich habs jetzt ausprobiert aber es kommt eine Fehlermeldung
bezgl. des & operators.

Was ist jetzt wieder falsch...

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Warum überhaupt char *transmit_byte und nicht einfach char
transmit_byte?

von Peter (Gast)


Lesenswert?

Weil der Übergabeparameter eine Adresse ist und dies wird im
Funktionskopf mit * gekennzeichnet...

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Und warum ist der Übergabeparameter eine Adresse?

von Peter (Gast)


Lesenswert?

Das ist so definiert bei den char Typen..

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Wo ist das so definiert? In deinem Programm. Und warum hast du es so
definiert? Was spricht dagegen, den char direkt zu übergeben?

von Olaf (Gast)


Lesenswert?

... gar nichts spricht dagegen; an dieser Stelle ist es sogar unsinnig
einen Pointer zu übergeben.

Olaf

von Peter (Gast)


Lesenswert?

Wie kann man das ganze ohne Pointer übergeben?
HAbs ausprobiert dann kommt eine Fehlermeldung...
Könntest Du mir mal den Code schicken?

PS. Ich hab nich gemeint das es von mir definiert wurde, sondern das es
in C notwendig ist, char-Zeichen so zu übergeben...

Danke Peter

von Olaf (Gast)


Lesenswert?

Hi Peter,

was hast du denn ausprobiert? So vielleicht:

int main( void ){
   transmit_databyte('a');
}

void transmit_databyte(char transmit_byte){
[...]
}

Olaf

von Peter (Gast)


Lesenswert?

Ja genau richtig das geht nicht, du brauchst einen *
im Funktionskopf vor dem transmit_byte !

von Peter (Gast)


Lesenswert?

Sorry Olaf Du hast recht es geht doch...
Allerdings weiß ich noch nicht warum ich bei folgenden Beispiel bei der
letzten zuweisung den * nicht benötige...???

int main( void )
{
   transmit_databyte('a');
}

void transmit_databyte(char *transmit_byte)
{
...
UDR=transmit_byte;/*warum hier keinen *transmit_byte???*/
}


Und was ist das für eine Adresse die ich hier übergebe...
Es müsste wenn es die adresse von a ist doch mit*Adr. der Inhalt also a
ausgegben werden oder

Verdammt ist das ein Sch...

Hilfe, für mich sehr wichtig

Danke für die Unterstütung

Peter

von Joerg Wunsch (Gast)


Lesenswert?

Du hast zwei Fehler begangen, die sich gegenseitig kompensieren:

. Du hast bei der Benutzung des Parameters transmit_byte die
  Dereferenzierung mit dem Stern vergessen

. Du hast beim Aufruf der Funktion keine Adresse, sondern einen
  Wert direkt übergeben.

Beides sollte dem Compiler eine Warnung wert sein, aber im Effekt
heben sich beide wieder auf.

Der Konstrukt »&'a'« ist übrigens unsinnig; da eine Zeichenkonstante
(im Gegensatz zu einer Zeichen/ketten/konstante, also "foo bar")
keinen Speicher selbst belegt, kann man von ihr auch keine Adresse
nehmen.

Peter, Deine Verwirrung rührt sicher von Zeichenkettenkonstanten her
(Strings), diese belegen immer Speicher (irgendwo, je nach Compiler),
und sie werden immer als Adresse des ersten Elements an Funktionen
übergeben, da sie technisch ein Array darstellen und Arrays stets per
Adresse vermittelt werden.  Daher müssen sie in der aufgerufenen
Funktion dann auch als Zeiger vereinbart und benutzt werden (wobei
eine Vereinbarung »char s[]« als Funktionsparameter völlig äquivalent
zu »char *s« ist).

von Peter (Gast)


Lesenswert?

Hallo Joerg,

Danke erst mal für Deine Hilfe, Du hast es richtig erfasst wo meine
Verwirrung her kommt (Array)...

Aber zu meinen Fehlern;

int main( void )
{
   transmit_databyte('a');
}

void transmit_databyte(char transmit_byte)
{
...
UDR=*transmit_byte;/*warum hier keinen *transmit_byte???*/
}

wenn ich es so mache kommt nicht das richtige raus

Wenn ich das letzte *auch weglasse kommt es richtig raus (Klar!)

Erklär mir bitte noch mal das mit meinen Fehlern die sich
gegenseitig aufheben vielleicht mit kleinen Beispielen das wäre echt
super da ich sonst noch am verzweifeln bin.
Die normalen Pointer bei int usw. hab ich ja verstanden

Vielen Dank

Peter

von Peter (Gast)


Lesenswert?

Hallo Joerg?

von Joerg Wunsch (Gast)


Lesenswert?

> Erklär mir bitte noch mal das mit meinen Fehlern die sich
> gegenseitig aufheben

Naja, Du hast eine Funktion, die deklariert worden ist, daß sie einen
Pointer übergeben bekommt (transmit_databyte()).  Entgegen der
Deklaration übergibst Du der Funktion anschließend aber eine
Zeichenkonstante.  Eine Zeichenkonstante ist aber weiter nichts als
eine (kleine) Integer-Zahl.  Die wird beim Aufruf in einen Zeiger
konvertiert, der halt auf die entsprechende Adresse zeigt, die durch
diese Zahl dargestellt würde.  Die Adresse ist natürlich unsinnig, sie
zeigt irgendwohin.  (In Wirklichkeit ist bei den hier betrachteten
Compilern diese Konvertierung ein rein syntaktischer Konstrukt, der in
der Praxis keinen einzigen Prozessorbefehl bewirkt.)

In der Funktion benutzt Du dann die Zeigervariable, ohne sie zu
dereferenzieren, d. h. Du benutzt letztlich die übergebene Adresse
wiederum als Integer-Zahl.  Syntaktisch wird sie dabei von einem
Zeiger in einen Integer umgewandelt, aber wiederum: dafür wird kein
Stück Code benötigt.  Es ist nur eine Betrachtungsfrage, ob ich die
Zahl im Registerpaar rr24.25 als Adresse oder als ganze Zahl ansehe.
Solange Deine Zeiger und Ganzzahlen die gleiche Anzahl von Bits haben
(bzw. der Zeiger in diesem Falle mehr als die 8-bit-Ganzzahl), geht
diese Methode gut, obwohl sie natürlich vom C-Standard in dieser Form
nicht garantiert wird.  Bei den meisten heutigen Maschinen
funktioniert das aber, lediglich bei einigen Exoten wurden Zeiger
u. U. intern anders dargestellt als Integer-Zahlen.

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.