Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

TigerClaw25

unregistriert

1

12.11.2013, 19:34

Zeiger als Rückgabetyp einer Funktion

wLHallo,

bei der SDL liefern SDL_SetVideoMode und andere einen Zeiger zurück. Verstehe es aber nicht.

Normal übergebe ich einem Zeiger die Adresse:

Int *pZeiger = NULL;

Mit dem Stern spreche ich den Wert an, ohne die Adresse.


Aber wie ist es bei einer Funktion. Wenn diese einen Zeiger zurück gibt, ist das mit *pFunktion mein Wert. Schreibe ich nur pFunktion habe ich die Adresse?

Also pZeiger = pFunktion();

Also zeigt Zeiger pZeiger auf Adresse der Funktion bzw dem Anfang oder? Wenn es eine normale Funkion wäre, wurde ich den Adressoperator verwenden. Da es aber ein Zeiger ist, der zurück gegeben wird, benoetige ich den Adressoperator nicht oder?

Und würde ich den Wert zuweisen wollen, mmüsste ich schreiben *pZeiger = *pFunktion(); ?

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

2

12.11.2013, 19:43

Du vermischt da glaub ich gerade Funktionszeiger und Zeiger als Returntyp.
SDL_SetVideoMode legt intern eine SDL_Surface auf dem Heap an (was das ist solltest du ja wissen). Dann initialisiert es diese SDL_Surface gemäß deinen Angaben und liefert dir einen Zeiger auf die SDL_Surface die ja nun auf dem Heap liegt zurück.

Das ist in etwa mit dem hier vergleichbar:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

int* foo(int wert) {
    int* integer = new int(wert);

    return integer;
}

int main() {
    int* my_ptr = foo(42);

    std::cout << *my_ptr << std::endl;
}
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

TigerClaw25

unregistriert

3

12.11.2013, 20:44

Also gibt return die Adresse zurück bzw per Aufruf von foo(42) erhalte ich die Adresse, auf die dann mein Zeiger zeigt.

my_ptr = foo(42);

Somit zeigt der Zeiger my_ptr auf die Adresse, wo der Wert der Funktion liegt?

Den Inhalt der Funktion kkönnte ich doch auch so schreiben oder:

int *Integer = NULL;
Integer = new int;

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »TigerClaw25« (12.11.2013, 20:55)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

12.11.2013, 21:13

Die Funktion gibt eine Speicheradresse in Form eines Pointers zurück.
my_ptr zeigt auf diese Adresse. Der RÜCKGABEwert der Funktion ist diese Adresse (aka der Pointer).

Den "Inhalt" der Funkion kannst du auch so schreiben. Es ändert aber nichts außer einer unnützen Zuweisung. Zudem ist "NULL" kein offizieller C++ Bezeichner. nullptr ist seit C++11 definiert.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

TigerClaw25

unregistriert

5

12.11.2013, 21:17

Vielen Dank für die Informationen. Das Thema ist zugegeben anfangs verwirrend. Zumal das ja noch nicht einmal eine komplexe Funktion ist. Ich habe manchmal Probleme mit dem * Operator, der ja direkt auf den Wert zugreift. Also habe ich in meinem Pointer die Adresse. Ich weiss nur nicht, wie ich mir einen Zeiger auf eine Funktion vorstellen soll. Denn eigentlich beinhaltet der RückgabeZeiger ja die Adresse. Aber warum einen Zeiger auf die Funktion? Verstehe den Anwendungsfall nicht. Einen Zeiger als Parameter ist doch einfacher.

Ich lese oft auch sowas wie FunktionsZeiger xyz: int * (*Funktion) ...... Soll ein Funktionszeiger sein. Woanders habe ich gelesen, dass solche Funktionen nur Adressen aaufnehmen können. Würde aber bedeuten, dass meine SDL_SetVideoModus ebenfalls nur Adressen erwarten würde. Bin verwirrt. Und im Buch sind Funktionszeiger, was mich hier verwirrt iSt die Zuweisung. Funktion1 = Funktion2

Int (*Funktion1) (int wert1, int wert2) und Funktion 2 ist eine einfache Funktion. Müsste da nicht bei der Zuweisung der Adressoperator? FUNKTION ist ja kein Array ... Müsste daher wie bei Variablen per & zugewiesen werden.


Und warum steht bei dir nach dem new int der Wert in Klammern new int(wert)?

Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »TigerClaw25« (12.11.2013, 23:57)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

13.11.2013, 15:02

Ich weiss nur nicht, wie ich mir einen Zeiger auf eine Funktion vorstellen soll. Denn eigentlich beinhaltet der RückgabeZeiger ja die Adresse. Aber warum einen Zeiger auf die Funktion? Verstehe den Anwendungsfall nicht.

Also, dein Code, den du oben gepostet hast, hat nichts mit Funktionszeigern zu tun.

Aber um deine Frage zu beantworten: Eine Funktion besteht aus Programmcode. Dieser Code liegt irgendwo im Speicher. Ein Funktionszeiger zeigt dort hin. Sein Typ enthält aber auch Informationen über den Rückgabewert der Funktion und ihre Parameter (= Signatur). Man benutzt sowas hauptsächlich für "Callbacks". Ein typisches Beispiel: Du möchtest, dass deine Funktion aufgerufen wird, wenn ein bestimmtes Ereignis eingetreten ist, z.B. wenn der Benutzer auf einen Button geklickt hat. Dann würdest du dem Button einen Zeiger auf deine Funktion geben, in der du auf den Klick reagierst, nach dem Motto "Hey Button, wenn du angeklickt wirst, ruf bitte diese Funktion hier auf!".

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

13.11.2013, 15:31

Er will gar keine Funktionspointer. Er will nur einen Pointer als Rückgabewert einer Funktion. Er hat sich da teilweise blöd ausgedrückt, aber passt schon.

Die Verwirrung dürfte daher kommen:
Also zeigt Zeiger pZeiger auf Adresse der Funktion bzw dem Anfang oder?
Das hat er falsch verstanden. Die Funktion wird gerufen und liefert einen Wert zurück - eine Adresse, bzw. ein Pointer, der irgendwohin zeigt.
Wenn ein Pointer auf den Anfang der Funktion im Speicher zeigen sollte, wäre das hier richtig:

C-/C++-Quelltext

1
2
3
void MyFunction(){...}
...
auto pFunctionPointer = MyFunction;

Das ist etwas anderes als

C-/C++-Quelltext

1
2
3
void* MyFunction(){...}
...
auto pFunctionPointer = MyFunction();

Beim Ersten macht man keinen Aufruf, beim Zweiten schon.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

13.11.2013, 15:34

@BlueCobold: Doch, wollte er, aber nur aus Interesse ;)

Ich lese oft auch sowas wie FunktionsZeiger xyz: int * (*Funktion) ...... Soll ein Funktionszeiger sein.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

13.11.2013, 15:36

Gut, das ist tatsächlich ein Funktionszeiger. Ist aber etwas ganz anderes als ein Zeiger als Rückgabewert einer Funktion - wie das Topic heißt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

13.11.2013, 15:50

Der * Operator kann halt verschieden eingesetzt werden.

C-/C++-Quelltext

1
2
3
4
5
6
int * meineVariable; // hier sagt der Operator, dass es sich um einen Zeiger auf einen Integer handelt
(*meineVariable) = 25; // hier wird der Operator zur Dereferenzierung eingesetzt. Du weißt nicht der Variable meineVariable den Wert 25 zu sondern der Speicherstelle auf die meineVariable zeigt. meineVariable ist ja nur ein Zeiger
int * TestFunktion123() // der Stern ist hier zu verstehen wie im ersten Fall. Das ganze ist in diesem Fall ein Rückgabewert einer Funktion
{
    return new int;
}


Du wirfst hier glaube ich beide Fälle durcheinander und denkst im Falle der Funktion würdest du dereferenzieren. Das ist aber nicht der Fall.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige