Forum: Mikrocontroller und Digitale Elektronik C-Verständniss


von Urs Müller (Gast)


Lesenswert?

Ich verstehe da etwas nicht:

typedef struct
{
uint8_t x;        // Anfangs x Variable
uint8_t y;        // Anfangs y Variable
uint8_t page;
} lcdCoord;

typedef uint8_t (*ks0108FontCallback)(const uint8_t*);
// Was Ist das ???????????????????

const uint8_t*    ks0108Font;

wie ist das mit der "Varible unit8_t" ? Ich habe da ein wennig
Probleme das zu verstehen ?
Kann mir jemanden sagen was unit8_t für ein typ ist und wie wird dieser
definiert ?

ich Danke für eine Antwort

Mit freundlichen Grüssen Urs

von Urs Müller (Gast)


Lesenswert?

Das ist auch noch in Programm ??

uint8_t ks0108CharWidth(char c);

Das Verstehe ich nicht was das ist. Vieleicht kann mir ja jemand hir
helfen.

Gruss Urs

von Karl H. (kbuchegg)


Lesenswert?

unit8_t
ist ein Datentyp, der festgelegt wurde um eine konstante Bit-
Zahl zu bekommen. Konkret: unsigned integer mit 8 Bit.

> typedef uint8_t (*ks0108FontCallback)(const uint8_t*);
> // Was Ist das ???????????????????

Das ist die Typ-Definition eines Funktionszeigers.
Konkret: Ein Funktionszeiger auf eine Funktion, die einen
         Pointer auf uint8_t annimmt (wobei der uint8_t auch
         noch konstant ist), und einen uint8_t zurueckliefert.

Der Typ der hier vereinbart wird, hat dann den Namen:
ks0108FontCallback

> uint8_t ks0108CharWidth(char c);

Das ist eine Prototypendeklaration einer Funktion.
Konkret sagt sie: Irgendwo gibt es eine Funktion namens
'ks0108CharWidth'. Diese Funktion nimmt einen char als Argument
und liefert einen uint8_t zurueck.

Speziell das Letztere bringt mich zu:
Du solltest Dir ein Buch ueber C zulegen und lesen. Funktions-
prototypen sind etwas absolut Normales in C und sowas wie
elementare Grundlagen.

von Urs Müller (Gast)


Lesenswert?

Danke für deine Antwort. Das letztere habe ich nun ich jetzt Vertanden.

Das mit dem Pointer ist mir nun klar.
typedef uint8_t (*ks0108FontCallback)(const uint8_t*);
(*ks0108FontCallback) ist der Poninter der auf unit8_t zeigt.

Was ich noch nicht verstanden habe ist das mit der Definition von der
unit8_t? Du sagst das ist ein Int. ich würde die defi. so machen.

typedef int unit8_t;
Dann ist ein neuer Datentyp mit dem Name unit8_t;

Diese Zeile finde ich leider nicht. Darum Weiss ich nicht warum du
weisst das es ein Int ist?

Ich danke dir für die Antwort.

Mit freundlichen Grüssen


urs Müller

von Rahul (Gast)


Lesenswert?

es ist ein 8-Bit Integer, also ein Byte bzw. unsigned char.
Guck mal in die int.h (oder so ähnlich), da werden die Datentypen so
vereinbart.

von Karl H. (kbuchegg)


Lesenswert?

> Das mit dem Pointer ist mir nun klar.
> typedef uint8_t (*ks0108FontCallback)(const uint8_t*);
> (*ks0108FontCallback) ist der Poninter der auf unit8_t zeigt

Aeh. Nein.

Zunaechst mal ist das nur eine Datentypdefinition. Sonst nichts.
Insbesondere ist es keine Variable in der man was speichern
koennte. Ist also sowas wie ein int, char, double, float, ...
Nur sieht er halt komplizierter aus.

Das ist ein Datentyp fuer einen Funktionszeiger.

Stell Dir vor Du hast eine Funktion:

uint8_t TestFnkt( const uint8_t* Argument )
{
  bla bla bla
}

So. Nun moechtest Du irgendwo einen Pointer auf diese Funktion
speichern, damit Du die Funktion indirekt ueber diesen Pointer
aufrufen kannst.
Wie muss der Datentyp fuer diesen Pointer sein?

  uint8_t * pFnkt;

kann nicht sein, den das obige ist ein Pointer auf einen uint8_t,
also eine Speicherzelle in der ein Wert gespeichert wird.
Also wie dann?

So (die Syntax muss man sich einfach merken):

  uint8_t (*pFnkt)( const uint8_t* );

Sieht ein bischen aus wie der Funktionskopf, nur dass der
Variablennamen in Klammern steht und ein * davor ist. So
was ist ein Funktionszeiger: pFnkt ist ein Zeiger auf eine
Funktion, wobei die Funktion einen const uint8_t Zeiger nimmt
und einen uint8_t zurueckliefert.

  Damit kann man dann schreiben:

uint8_t TestFnkt( const uint8_t* Argument )
{
  bla bla bla
}

int main()
{
  uint8_t i;
  uint8_t (*pFnkt)( const uint8_t* );  /* Zeiger definieren */

  pFnkt = TestFnkt;                    /* Die Funktion zuordnen */

  (*pFnkt)( &i );                      /* Die Funktion ueber den
                                          Zeiger (also indirekt)
                                          aufrufen */
}

Nun ist es aber muehsam, fuer eine Variablendeklaration immer
diesen Rattenschwanz uint8_t (*xyz)( const uint8_t* ) zu schreiben.
Daher macht man sich einen Typedef:

typedef uint8_t (*ks0108FontCallback)(const uint8_t*);

und hat damit einen neuen Namen fuer den Datentyp
uint8_t (*)( const uint8_t* )
kreiert und kann diesen ganz normal (so wie int, char, double, ...)
verwenden:

typedef uint8_t (*ks0108FontCallback)(const uint8_t*);

uint8_t TestFnkt( const uint8_t* Argument )
{
  bla bla bla
}

int main()
{
  uint8_t i;
  ks0108FontCallback pFnkt;            /* Zeiger definieren */

  pFnkt = TestFnkt;                    /* Die Funktion zuordnen */

  (*pFnkt)( &i );                      /* Die Funktion ueber den
                                          Zeiger (also indirekt)
                                          aufrufen */
}

Ist es jetzt klarer?

Uebrigens:
> typedef int unit8_t;
> Dann ist ein neuer Datentyp mit dem Name unit8_t;

typedef erzeugt keine neuen Datentypen. typedef gibt bereits
vorhandenen Datentypen einen neuen Namen (einen 'Alias' (englisch)).
Das ist ein kleiner, feiner Unterschied.

Im uebrigen hab ich nicht gesagt, dass ein uint8_t ein int ist.
Was ich gesagt habe ist: es ist ein unsigned integer mit 8 bit.
Und in C (zumindest auf einem AVR) ist der Datentyp der genau
das erfuellt (unsigned integer mit 8 bit) ein 'unsigned char'

typedef unsigned char uint8_t;

Der kommt aus irgendeinem #include File, das du vorher inkludiert
hast.

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.