WCM Forum

WCM Forum (http://www.wcm.at/forum/index.php)
-   Programmierung (http://www.wcm.at/forum/forumdisplay.php?f=17)
-   -   Funktionszeiger in C (http://www.wcm.at/forum/showthread.php?t=58720)

The_Beax 05.06.2002 18:18

Funktionszeiger in C
 
Hallo Leute!

Ich schreibe ein Programm in C, dass Daten auf verschiedene Arten sortiert. Ich verwende für das Sortieren die Funktion gsort und die Vergleichsfunktionen schreibe ich selbst. Aber der Compiler (gcc) meldet mir einen Fehler im 4 Argument.

Prototyp von qsort:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

Aufruf:
qsort(aData, MAX, sizeof(data_t *), compare);

Die Funktion "compare" ist natürlich ordnungsgemäß deklariert.

Weiß jemand wo der Fehler liegt?

MfG
Martin

irrsinn 06.06.2002 11:14

wär vielleicht gut, wenn du den ganzen source + die exakte compiler fehlermeldung posten könntest.

PredeX 06.06.2002 12:02

Wenn ich mir den Prototypen
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

und das mit deinem Aufruf vergleiche:
qsort(aData, MAX, sizeof(data_t *), compare);

dann scheint es, dass es notwendig ist, dass du bei compare vergessen hast, zwei const void * (siehe prototyp) anzugeben. Schau mal in der Hilfe was das für Werte sein solln.

PredeX

PS: Ich hoffe ich habe mich verständlich ausgedrückt...:confused:

The_Beax 06.06.2002 17:00

Hallo Leute!

@irrsinn
fp.c:57: warning: passing arg 4 of `qsort' from incompatible pointer type

@PredeX
Die Funktion compare ist zb strcmp und bei Funktionszeiger darf ich meines Wissens ja keine Parameter angeben sonst wird der Compiler den Syntay eher als Funktionsaufruf interpretieren.

Bsp:
qsort(aData, MAX, sizeof(char *), strcmp);

Die Werte können praktisch alles ein char *, int, double, Strukturen, ... . Das kommt auf die Funktion an.

MfG
Martin

PredeX 06.06.2002 18:10

also ich habe jetzt in meinem "schlauen buch" nachgesehen, und folgendes gefunden:

Zitat:

Die Vergleichsfunktion compare muss normalerweise selbst definiert werden. Die Parameter dieser Funktion sind zwei Zeiger auf die Vektorelemente, die zu vergleichen sind. Die Zeiger werden als "typenlose Lesezeiger" deklariert.
Deshalb meine Frage: Hast du eine solche Funktion deklariert, und sieht sie ungefähr wie folgt aus?
Code:

int compare( const void *p1, const void *p2)
{
  if(  *(int *)p1 > *(int *)p2 ) retrun (1);
  // ersetze (int *) durch den Datentypen den du bei deinem Array verwendest
  else if( *(int *)p1 < *(int *)p2 ) return (-1);
  // ersetze (int *) durch den Datentypen den du bei deinem Array verwendest
  else                              return (0);
}

Die Returnwerte entsprechen dann denen die qsort() verwendet um zu entscheiden, wie die Werte zu sortieren sind:

Zitat:

Der Return-Wert ist kleiner als 0, gleich 0, oder größer als 0, je nachdem ob das erste Vektorelement kleiner, gleich oder größer als das zweite Element ist.
Hoffe ich konnte weiterhelfen...

PredeX

The_Beax 06.06.2002 19:35

Hallo Leute!

@PredeX
Das ist mir natürlich klar nur funktioniert anscheinend mein Syntax nicht. Denn wenn ich qsort mit einem 4 Paramter "strcmp" (Das ist eine Vergleichsfunktion die den von dir genannten Anforderungen entspricht) bekomme ich oben geposteten Fehler. Wie man die Funktion implementiert darf man schon selbst entscheiden :-). Grundsätzlich geht es mir ja nur darum zu wissen wie ich einen Funktionszeiger die Funktion als Parameter übergebe. Ich dachte nur der Funktionsname reicht:

zB
qsort(aArray, MAX, sizeof(daten_typ), strcmp);

aber anscheinend funktioniert, dass nicht so.
Trotzdem Danke für deine Antwort.


MfG
Martin

helmix 07.06.2002 12:37

Der gcc compiler ist ganz schön schlau, er hat nämlich recht!
Der Visual C Compiler compiliert das dagegen ohne Murren (nur funkt. das Programm dann nicht)

Der Fehler ist folgender:
Ich nehme an, dein aArray ist ein Array von Strings, d.h. ein Pointer
auf Pointer von chars!
qsort 'füttert' die compare funktion mit pointern auf jeweils 2 Array-Einträge,
in unserem Fall also char** und nicht char*, wie es der strcmp gern hätte!!
Die Folge ist, dass so die Pointer im Array sortiert werden und nicht die Strings, sofern der strcmp da überhaupt mitspielt :eek:

Abhilfe:
Du musst doch eine eigene compare funktion schreiben, die so aussieht:

int compare(const void *arg1, const void *arg2)
{
return strcmp(*((char**)arg1), *((char**)arg2));
}

Damit sollte es dann funktionieren!

lg.
helmix


Alle Zeitangaben in WEZ +2. Es ist jetzt 19:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag