Forum: Compiler & IDEs Zeiger?


von Peda (Gast)


Lesenswert?

Hallo dort..

ich habe einen Quellcode wo am Anfang dies steht:
static CycleType nCycle = 0;

Später wird dann aufgerufen:
GetTime(&nCycle);  //Funktion speichert einen Time-Wert an die Stelle 
&nCycle

Das & bedeutet doch einen Zeiger auf ein Array oder?
Aber es ist doch kein Array, nur ein Einzelwert...nämlich 0
Und warum muss das Static vor die Deklaration?

Welcher Sinn steckt dahinter?

von Karl H. (kbuchegg)


Lesenswert?

Nein.

& ist einfach nur der Adress-Of Operator. Er liefert die Adresse
des angegeben Dinges.

> Aber es ist doch kein Array, nur ein Einzelwert...nämlich 0

Den & interessiert die 0 überhaupt nicht.
&nCycle liefert die Adresse im Speicher, an der die Variable
nCycle erzeugt wurde. Welchen Inhalt diese Variable hat, ist
dem & völlig egal.

Wozu benötigt die Funktion aber die Adresse?

Ganz einfach: In C wird alles (mit 1 Ausnahme) als sog.
'Call by Value' übergeben. D.h. wenn du machst:
1
void foo( int i )
2
{
3
  i = 5;
4
}
5
6
int main()
7
{
8
  int k = 8;
9
  foo( k );
10
}

Dann wird bei Aufruf der Funktion foo der Wert von k (der 'Value')
aufgesucht. In diesem Fall 8. Dieser Wert wird an die Funktion
foo übergeben und wird beim Betreten der Funktion an die lokale
Variable i zugewiesen. Innerhalb von foo() kann der Wert von
i auch verändert werden, nur hat diese Änderung natürlich
keine Auswirkungen auf k. foo(), und damit auch i, wissen nichts
von einem k, dass für den Aufruf benutzt wurde. Der Aufruf
hätte genauso gut auch
1
int main()
2
{
3
  foo( 8 );
4
}
lauten können. Für foo() würde das keinen Unterschied machen.

Nur: Manchmal möchte man genau das nicht!
Manchmal möchte man, dass eine Funktion die Möglichkeit hat,
eine Variable vom Aufrufer zu verändern.

In so einem Fall übergibt man der Funktion die Adresse einer
Variablen. Die Adresse der Variablen ermöglicht dann der Funktion
über diese Adresse die Variable beim Aufrufer zu verändern:
1
void foo( int* pI )
2
{
3
  *pI = 5;
4
}
5
6
int main()
7
{
8
  int k = 8;
9
  foo( &k );
10
}

Jetzt bekommt foo() die Adresse von k mitgegeben. Diese Adresse
ermöglicht foo() auf den Speicher zuzugreifen, an dem die Variable
k erzeugt wurde. Nach dem Aufruf von foo() hat k also einen
neuen Wert, nämlich 5. Ganz im Gegensatz zum ersten Beispiel,
in dem k nach Aufruf der Funktion immer noch den selben Wert, 8,
hat, den es auch vor Aufruf der Funktion hatte.

********

static kann mehrere Bedeutungen haben, ja nachdem wo es konkret
eingesetzt wird.

static auf globalen Variablen schränkt die Sichtbarkeit einer
Variable ein. Diese Variable ist dann nur noch in dem *.c File
sichtbar (und damit ansprechbar), in der die 'globale' Variable
definiert wurde. Es ist dann nicht mehr möglich sich von einem
anderen *.c File mittels 'extern' auf diese Variable zu beziehen.

static auf eine funktionslokale Variable bewirkt, dass diese
Variable nicht wie andere funktionslokale Variablen bei Ver-
lassen der Funktion zerstört wird. Sie überlebt also das
Verlassen der Funktion und hat beim nächsten Aufruf dieser
Funktion wieder denselben Wert. In einem gewissen Sinne ist
do eine Variable also ebenfalls eine globale Variable, nur
dass deren Sichtbarkeit auf nur die Funktion, in der die
sie definiert wurde, beschränkt ist.

All das findet sich aber auch in jedem schlechteren Buch
über C. Ich empfehle dringend, sich ein Buch über die
Sprache C zu kaufen. Empfehlenswert ist immer noch der
Klassiker 'Kernighan & Ritchie', der dir die Sprache in
einer systematischen Art und Weise und vor allen Dingen
vollständig beibringt.

von Thomas S. (thomass)


Lesenswert?

Hallo Programmierer,

ich bin über einen Code gestolpert und möchte diesen verstehen.
Es ist ein Zeiger soweit habe ich es verstanden doch das ganze gebilde 
verstehe ich nicht.
Vielleicht kann es mir ja jemand erklären
1
typedef struct
2
{
3
    unsigned char state;
4
    char  *pText;
5
    char (*pFunc)(char input); // diese Zeile  ?!?!?!?!?!?????:-)
6
} MENU_STATE;

Gruß

Thomas

von Simon K. (simon) Benutzerseite


Lesenswert?

Thomas S. wrote:
1
    char (*pFunc)(char input); // diese Zeile  ?!?!?!?!?!?????:-)

Die Zeile definiert einen sogenannten Funktionszeiger/Function-pointer. 
Das heißt: Genau wie man über eine Adresse einer Variable und dem 
*-Operator auf den Inhalt der Variable an dieser Adresse zugreifen kann, 
gibt es auch die Möglichkeit einem Zeiger die Adresse einer Funktion 
zuzuweisen.
Der *-Operator hat nun aber fast die gleiche Funktion: Mit ihm lässt 
sich die an der angegebenen Adresse liegende Funktion aufrufen:
1
char Param = 5;
2
char Return;
3
4
Return = (*pFunc) (Param);

Zu der Syntax kann man nur sagen: Sie sieht wirklich sehr verwirrend 
aus. Wenn man aber erstmal ordentlich damit herumgearbeitet hat, dann 
gewöhnt man sich daran.

Noch ein paar Erklärungen zu der Zeile oben: Der Funktionszeiger kann 
nur Adressen von Funktionen aufnehmen, welche einen den Return-Typ 
"char" haben, und genau einen Parameter vom Typ "char" aufnehmen. Wo du 
diese Information nun wiederfindest kannst du ja sicher selbst 
herausfinden ;)

von Thomas S. (thomass)


Lesenswert?

OK habe mein Buch mal weitergeblättert.
Unter komplizierte Vereinbarungen steht hierzu etwas.

Habe ich es richtig verstanden?!?!?

Es handelt sich um einen Pointer pFunc der als Datentyp char ist, er 
zeigt auf einen Funktion deren der "char input" übergeben wird und die 
einen char Wert zurückliefert.

Ach du Sch.....se.

Ich hoffe das kapiert jemand.

Thomas

von Simon K. (simon) Benutzerseite


Lesenswert?

Thomas S. wrote:
> OK habe mein Buch mal weitergeblättert.
> Unter komplizierte Vereinbarungen steht hierzu etwas.
>
> Habe ich es richtig verstanden?!?!?
>
> Es handelt sich um einen Pointer pFunc der als Datentyp char ist, er
> zeigt auf einen Funktion deren der "char input" übergeben wird und die
> einen char Wert zurückliefert.
>
> Ach du Sch.....se.
>
> Ich hoffe das kapiert jemand.
>
> Thomas

Siehe oben ;)

von Thomas S. (thomass)


Lesenswert?

@Simon,

ja hatte ich gestern schon gesehen, habe wohl gleichzeitig gepostet.
Auf alle Fälle Danke für die Antwort.

Thomas

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.