Frage zum casting von pointern

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Frage zum casting von pointern

Beitrag von Bruno » Mo Dez 05, 2011 10:07 am

Hallo!

ich habe hier einen Fehler, dem ich mit meiner vorhandenen Literatur nicht auf die Spur komme.

Ich möchte eine ID eines Elements aus einem GUI lesen.

Dazu habe ich in der Headerdatei einer API die ich verwenden will folgendes gefunden:

Code: Alles auswählen

/*ID          I   int     internal property ID*/
/*extID       O   int     external property ID*/
 int (*IdGet )(int id, int *extid, );
Ich übergebe also id und bekomme extid zurück.

Ich schreibe dann im source:

Code: Alles auswählen

int i;
int* ext;
int extPID;
//div. Code
for (i=0;i<Anzahl;i++){
  ptrTabl->Props->IdGet(i,ext);
  extPID=ext;
// div. Code
}
Das ich hier einen Bock schieße, weil ext vom Typ int* ist und extPid vom Typ int ist mir klar, daher habe ich versucht das irgendwie zu casten, aber der Compiler meckert immer diese Zeile an.

Kann mir jemand erklären wie ich das casten kann oder hat jemand eine elegantere Idee?

Ciao

Bruno
"21" ist nur die halbe Wahrheit...

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Frage zum casting von pointern

Beitrag von Xin » Mo Dez 05, 2011 10:15 am

Bruno hat geschrieben:Ich möchte eine ID eines Elements aus einem GUI lesen.

Dazu habe ich in der Headerdatei der API folgendes gefunden:

Code: Alles auswählen

/*ID          I   int     internal property ID*/
/*extID       O   int     external property ID*/
 int (*IdGet )(int id, int *extid, );
Ich übergebe also id und bekomme extid zurück.

Ich schreibe dann im source:

Code: Alles auswählen

int i;
int* ext;
int extPID;
//div. Code
for (i=0;i<Anzahl;i++){
  ptrTabl->Props->IdGet(i,ext);
  extPID=ext;
// div. Code
}
Das ich hier einen Bock schieße, weil ext vom Typ int* ist und extPid vom Typ int ist mir klar, daher habe ich versucht das irgendwie zu casten, aber der Compiler meckert immer diese Zeile an.

Kann mir jemand erklären wie ich das casten kann oder hat jemand eine elegantere Idee?
Hier gibt's erstmal ein Mißverständnis. Die API gibt Dir vor, einen Zeiger auf eine int zu übergeben. Das bedeutet nicht zwangsläufig, dass hier ein Zeiger an die Funktion als Eingabe übergeben werden soll, hier ist eigentlich eine Ausgabe-Referenz gefragt: Hier geht die Information rein, wo der Speicher steht, in den das Ergebnis stehen soll.

Der Speicher für das Ergebnis ist bei Dir das "int" (nicht int*!) mit dem Namen extPID. Du brauchst nun die Adresse von diesem Speicherbereich: &extPID. Das ist vom Datentyp dann ebenfalls ein Zeiger auf int.

Code: Alles auswählen

for (i=0;i<Anzahl;i++){
  ptrTabl->Props->IdGet(i,&extPID);
// div. Code
}
Solltest Du soetwas in C++ selbst schreiben, geht das eleganter mit Referenzen. C-Programmierer behelfen sich mit Zeigern.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Re: Frage zum casting von pointern

Beitrag von Bruno » Mo Dez 05, 2011 10:26 am

Hallo!

Erstmal danke für die Antwort, der Fehler ist damit weg.

Aber nochmal zum Verständnis:
In der Headerdatei steht:

Code: Alles auswählen

/*ID          I   int     internal property ID*/
/*extID       O   int     external property ID*/
int (*IdGet )(int id, int *extid, );
Die Funktion IdGet erwartet von mir ein int (id) und liefert ein int* , d.h. einen pointer auf ein int zurück (extid), oder?

Deine Erklärung zur Antwort verwirrt mich ein wenig...

Ciao

Jürgen
"21" ist nur die halbe Wahrheit...

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Frage zum casting von pointern

Beitrag von Xin » Mo Dez 05, 2011 11:37 am

Bruno hat geschrieben:Die Funktion IdGet erwartet von mir ein int (id) und liefert ein int* , d.h. einen pointer auf ein int zurück (extid), oder?
Nein, die Parameter sind in C immer Eingabeparameter. Du gibst die Adresse REIN, an die die Funktion das Ergebnis "extPID" schreiben soll. Du übergibst also die Information, wo sich extPID im Speicher befindet und die Funktion schreibt dann ihr Ergebnis da hin.
Bruno hat geschrieben:Deine Erklärung zur Antwort verwirrt mich ein wenig...
Es ist vergleichbar mit einem Kauf bei EBay. Du übergibst dem Verkäufer Deine Adresse und der Verkäufer sorgt dafür, dass sich die Ware in Deinem Briefkasten materialisiert, obwohl Du ihm nicht den Briefkasten geschickt hast. ;-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Re: Frage zum casting von pointern

Beitrag von Bruno » Mo Dez 05, 2011 3:34 pm

Hallo!

OK, habe mich da falsch ausgedrückt oder es noch nicht verstanden:

Code: Alles auswählen

int FUNKTION (int , int, int, int, int,int,int);
[...]
int FUNKTION (A1,  A2, B1, B2, M, B){
int retval;
[...]
return(retval);
int Funktion definiert den Rückgabetyp von FUNKTION, wobei der Wert mit return(retval) zurückgegeben wird und A!, A2,...bis B sind die Übergabeparameter.

Das funktioniert solange, bis ich mehr als einen Rückgabewert aus einer Funktion benötige.

Benötige ich eine Funktion, bei der aus einem oder mehrern Parametern mehrere andere Parameter berechnet werden, verwende ich retval gar nicht oder als Fehlernummer.

Beispiel: Ich habe zwei Punkte in einer Ebene und will die Parameter der Geradengleichung (Steigung M und Y-Achsenabschnitt B) daraus berechen.
Dann wären A1, A2, B1, B2 in diesem Sinne "Eingabe"-Parameter und M und B "Rückgabe"-Parameter.

So ist m.E. auch IdGet definiert:

Code: Alles auswählen

/*ID          I   int     internal property ID*/
/*extID       O   int     external property ID*/
int (*IdGet )(int id, int *extid );
Der Parameter id "geht rein" und der Parameter extid "geht raus" und ich bekomme dann einen int-pointer auf extid.

Oder bin ich da vollkommen falsch?

Ciao

Bruno

P.S. float wäre besser gewesen, aber habe keinen Bock das nochmal zu schreiben... tun wir so als gäbs nur natürliche Zahlen ;)
"21" ist nur die halbe Wahrheit...

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Frage zum casting von pointern

Beitrag von Xin » Mo Dez 05, 2011 3:52 pm

Bruno hat geschrieben:Der Parameter id "geht rein" und der Parameter extid "geht raus" und ich bekomme dann einen int-pointer auf extid.

Oder bin ich da vollkommen falsch?
Yepp ;-)

Parameter gehen immer in die Funktion rein. Niemals raus. Never ever. Das Einzige, was raus geht ist der Rückgabeparameter vor dem Funktionsnamen, den Du mit "return retval" zurückgibst.

'extid' ist ja ein Pointer, eine Adresse. Es geht also die Adresse(!) von der Variablen extid rein. Die Funktion geht dann hin und schreibt an die Adresse, die Du REINgibst, das Ergebnis:

Code: Alles auswählen

int IdGetImplementation( int id, int * extId )
{
  ...
  *extId = id;                  // Verwendung des Eingabeparameters 'extId')
                                     // Die Funktion schreibt an die Adresse, die in extId beschrieben steht

  return EXIT_SUCCESS;  // Rückgabeparameter
}
Wenn Du in main() nun die Adresse Deiner Variablen extPID übergibst:

Code: Alles auswählen

int i;
int extPID;
//div. Code
for (i=0;i<Anzahl;i++){
  ptrTabl->Props->IdGet(i, &extPID);
// div. Code
}
Dann wird die Adresse für den Speicherplatz "extPID" in die Funktion IdGet REINgesteckt und die Funktion schreibt das Ergebnis dahin, wo die Variable extPID liegt.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Re: Frage zum casting von pointern

Beitrag von Bruno » Di Dez 06, 2011 12:51 pm

Hallo!

OK, wir jetzt ist kalr: wir reden aneinander vorbei: Du beschreibst die reine Lehre wonach eine Funktion immer nur einen Rückgabewert hat.

Ich meinte das vom Standpunkt der Variablenberechnung im Programm:
In meinem Beispiel mit der Geradengleichung sind M und B VOR dem Aufruf der Funktion unbekannt und NACH dem Aufruf bekannt.
Daher würde ich (zugegebenermaßen umgangssprachlich) sagen: Die Funktion "bekommt" die Koordinaten von zwei Punkten und "liefert" die Steigung und den Y-Achsenabschnitt. Und so ist auch die Doku in den Headerdateien die ich verwende gemeint:

Code: Alles auswählen

EID          I   int     Element ID
Type       I   int     Type of Element
Active     O   int     Element activated TRUE/FALSE
Length    O float     Length of Element
Die mit I bezeichneten Parameter mussen VOR dem Funktionsaufruf bekannt sein, die mi O bezeichneten Parameter werden von der Funktion bestimmt.

Ciao

Jürgen
"21" ist nur die halbe Wahrheit...

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Frage zum casting von pointern

Beitrag von Xin » Di Dez 06, 2011 1:32 pm

Bruno hat geschrieben:OK, wir jetzt ist kalr: wir reden aneinander vorbei: Du beschreibst die reine Lehre wonach eine Funktion immer nur einen Rückgabewert hat.

Daher würde ich (zugegebenermaßen umgangssprachlich) sagen: Die Funktion "bekommt" die Koordinaten von zwei Punkten und "liefert" die Steigung und den Y-Achsenabschnitt. Und so ist auch die Doku in den Headerdateien die ich verwende gemeint:
Die Informatik ist voller ambivalenter Begrifflichkeiten. Im Prinzip weiß kein Informatiker, was der andere erzählt, wenn man vorher nicht kurz einen Abgleich der Vokabeln macht. Das alleine macht die Sache allgemein schon recht kompliziert.
"Umgangssprachlich" die Sache weiter zu verwaschen führt zu einem schlechtem Verständnis. Du übergibst Parameter IN die Funktion, die die Funktion benötigt, um Daten RAUSzuschreiben, die also für die Ausgabe benutzt werden.

Vergleiche das mit einem FILE* oder ostream-Objekt. Du gibst das Objekt REIN, damit in die Datei ausgegeben werden kann. Der FILE * bzw. das ostream-Objekt ist nicht die Ausgabe, sondern die Datei auf der Festplatte. Genauso beim int*: nicht der int * ist die Ausgabe, sondern der Speicher, wohin gezeigt wird. Es wird zur Ausgabe genutzt (O), aber es bleibt ein EINGABEparameter.

Wenn Du verstehen willst, was Du tust, dann sollte das nicht umgangssprachlich sein. Entsprechend verpasse ich als Antwort nicht nur die 21 ;-D
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten