Funktionszeiger in Struktur

OP #961536
Lesenswert?

Hallo,

Ich habe folgende Struktur definiert:

typedef struct
{
    ubyte    State;
    ubyte    PrevState;
    ubyte    Error;
    void     (*ChangeState)(ubyte);
} Status;

Darin enthalten ist ein Zeiger (ChangeState), der auf folgende Funktion 
zeigt: void changeState(ubyte newState)

In meiner Main-Routine deklariere und initialisiere ich eine Variable 
von diesem Typ:

void main(void)
{
         Status a;
         ubyte newState = 1;

  a.PrevState = NULL;
  a.State = stateInit;
  a.Error = noError;
  a.ChangeState = changeState;  // zuweisung des zeigers auf fkt.

         // aufruf der funktion
         a.ChangeState(newState);
         ...
}

meine Frage lautet nun:
Wie muss void changeState(ubyte newState) aufgebaut sein, damit ich 
darin den Wert von a.State ändern kann? Gibt es in C eine Art "this" mit 
der man auf die members der Struktur zugreifen kann?

Gruß
Stefan
Moderator Persönliche Seite #961539
Lesenswert?

Nein, sowas gibt es in C nicht.  Du müsstest den this-Zeiger explizit
übergeben:
1
typedef struct status
2
{
3
    ubyte    State;
4
    ubyte    PrevState;
5
    ubyte    Error;
6
    void     (*ChangeState)(struct status *, ubyte);
7
} Status;
8

9
...
10

11
void main(void)
12
{
13
         Status a;
14
         ubyte newState = 1;
15

16
  a.PrevState = NULL;
17
  a.State = stateInit;
18
  a.Error = noError;
19
  a.ChangeState = changeState;  // zuweisung des zeigers auf fkt.
20

21
         // aufruf der funktion
22
         a.ChangeState(&a, newState);
23
         ...
24
}

Übrigens ist das keine Initialisierung, sondern eine Zuweisung.  Als
Initialisierung würde es wie folgt aussehen:
1
void main(void)
2
{
3
         Status a = {
4
             .PrevState = NULL,
5
             .State = stateInit,
6
             .Error = noError,
7
             .ChangeState = changeState
8
         };
9
         ubyte newState = 1;
10

11
         // aufruf der funktion
12
         a.ChangeState(&a, newState);
13
         ...
14
}
Gast #961551
Lesenswert?

@Jörg Wunsch: Ohne jetzt Klugschei.... spielen zu wollen habe ich eine 
Frage zu deinem Posting. Ich bin nämlich noch nicht so ganz fitt in C 
und möchte das hier lieber geklärt haben, bevor es mich doch noch mehr 
verwirrt oder ich etwas falsches "lerne". Du hast folgendes geschrieben:
1
typedef struct status
2
{
3
    ubyte    State;
4
    ubyte    PrevState;
5
    ubyte    Error;
6
    void     (*ChangeState)(struct status *, ubyte);
7
} Status;
8

9
...
10

11
void main(void)
12
{
13
         Status a;
14
         ...
15
}

Mir geht es hier speziell um den typedef und die Deklaration der 
Variablen a. Dein typedef ist doch so nicht korrekt oder? Du hast nach 
meinem bisherigen Verständnis ja nicht nur einen neuen Datentyp "status" 
angelegt, sondern auch gleich im typedef eine Variable "Status" mit dem 
Datentyp "status" oder? Somit müsstes es in der main() nur "status a;" 
heißen, stimmts?
Dieser Code soll nochmal zeigen, wie ich gedacht hätte, dass es richtig 
ist:
1
typedef struct
2
{
3
    ubyte    State;
4
    ubyte    PrevState;
5
    ubyte    Error;
6
    void     (*ChangeState)(struct status *, ubyte);
7
} status;
8

9
...
10

11
void main(void)
12
{
13
         status a;
14
         ...
15
}
Oder liege ich mal wieder völlig falsch?
#961594
Lesenswert?

> Du hast nach meinem bisherigen Verständnis ja nicht nur einen neuen
> Datentyp "status" angelegt, sondern auch gleich im typedef eine
> Variable "Status" mit dem Datentyp "status" oder?

Nein, er hat den neuen Typ Status aus der Struktur status gebildet.
Man könnte hier auch schreiben:
1
typedef struct
2
{
3
...
4
} Status;
Dann besteht der neue Typ aus einer anonymen Struktur.

1
int i;
-> Variable i

1
typedef int i;
-> neuer Typ i

1
struct
2
{} Status;
-> Variable Status

1
typedef struct
2
{} Status;
-> neuer Typ Status
Gast #961600
Lesenswert?

Achso, dann ist bei dem typedef also der Begriff nach dem Wort "struct" 
nur der Name der Struktur und nicht schon die Bezeichnung des neu 
erstellten Datentyps. Das erklärt natürlich einiges :).

Danke und Gruß,
Marian
Persönliche Seite #961671
Lesenswert?

Stefan Ernst wrote:
>> Du hast nach meinem bisherigen Verständnis ja nicht nur einen neuen
>> Datentyp "status" angelegt, sondern auch gleich im typedef eine
>> Variable "Status" mit dem Datentyp "status" oder?
>
> Nein, er hat den neuen Typ Status aus der Struktur status gebildet.
> Man könnte hier auch schreiben:
>
1
> typedef struct
2
> {
3
> ...
4
> } Status;
5
>

Nein, das ginge nicht, weil man innerhalb der Struktur ja einen struct 
status * für den Prototypen der Member-Funktion braucht. Daher darf die 
Struktur nicht anonym sein und muss benamt werden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren