|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
function pointer stuff
this function call line is confusing me a bit:
Code:
qsorty((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(fold ? strcmpulc : strcmp)); i don't understand what the (void **) part is. it doesn't match up with the qsorty decleration which is: Code:
void qsorty(void *lineptr[], int left, int right, int (*comp)(void *, void *)); also the (int (*)(void *, void *))(fold ? strcmpulc : strcmp) part from the function call i kind of understand. it seems that it's working a bit like the %d's in a printf statement - the place holder is getting replaced. so (*) is getting replaced by the answer to fold ? which is going to be one of the two pointers to functions. what is that makes it behave like that? is that something to do with the (void **) maybe? (i'm guessing) also, say you've got a situation where there isn't any option about which function pointer should be passed (like in the (fold ? strcmpulc : strcmp) part), is this the only way to say that? : Code:
qsorty((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(numcmp)); that works but it seems like it should be possible to use something like: Code:
qsorty((void **) lineptr, 0, nlines-1, (int (*numcmp)(void *, void *))); or Code:
qsorty((void **) lineptr, 0, nlines-1, (*numcmp)(void *, void *)); but they aren't ok. |
|
#2
|
||||
|
||||
|
Quote:
Bear in mind that in a function declaration (and only in a function declaration!) pointer-to-type and array-of-type are identical; they're synonymous, and the only reason why you might want to choose array-of-type (type[]) over pointer-to-type (type*) is as a hint to the programmer that it doesn't point to a single element of type, but to the first in a sequence of type. In the function call I assume that lineptr is an array of pointer-to-char, which is why the typecast to (void **) makes sense, being that in a function declaration, **void is identical to *void[] as I just explained. Quote:
Let's break that up into two pieces, the first part being a typecast, and the second being the conditional operator: The (fold ? strcmpulc : strcmp) bit is fairly straight-forward; it's the conditional operator ?: (check A7.16 on page 208 of K&R if you're unfamiliar with it). Basically that expression evaluates to either strcmpulc or strcmp, depending on the value of fold. So what you get, is a function pointer. The problem is that qsorty expects a pointer to a function that has a prototype of Code:
int (*cmp)(void *, void *) , but strcmp and strcmpulc are (probably) declared as Code:
int (*cmp)(const char *, const char *) That's what the typecast is for. It might look draconian, but yes, it really is a typecast. It casts the pointer-to-function-with-two-pointer-to-char-arguments-and-returning-an-intto a pointer-to-function-with-two-pointer-to-void-arguments-and-returning-an-int. Code:
int (*)(void *, void *) can be broken down as follows: Code:
int /* returning an int */ (*) /* pointer-to */ (void *, void *) /* function with two pointer-to-void arguments */ It needs the parentheses around the asterisk (the pointer-to bit) to make sure it isn't associated with the return type, int. I hope this clears things up a bit. Keep asking though; it keeps us on our toes ![]()
__________________
"A poor programmer is he who blames his tools." http://analyser.oli.tudelft.nl/ |
|
#3
|
|||||
|
|||||
|
thanks for your reply.
Quote:
they're just declared normally : Code:
int strcmpulc(char *, char *); and the other is part of string.h so it's also declared in the usual way. maybe that's why i get : warning: pointer type mismatch in conditional expression for that line? probably is. but then saying that, on this function call line:Code:
qsorty((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(numcmp)); i don't get that warning and numcmp is declared like so: Code:
int numcmp(char *, char *); Quote:
i understand that apart from why, when there's no conditional aspect - only one possible function to call, can i not say: Code:
(int (*strcmp)(void *, void *)) or something similar? does it have to be in two pieces even when no conitional element? (in the call to the function that is) Quote:
a bit, yes thanks i need to go over it a bit more to let it sink inLast edited by balance : April 9th, 2003 at 08:57 AM. |
|
#4
|
|||||
|
|||||
|
Quote:
Well, my emphasis wasn't on the consts, but the fact that it's char* instead of void*. Quote:
The code snippet above is just a semi-colon short of a declaration statement. It would declare strcmp as being a pointer-to-function. What the qsorty function call contains though, is a type cast, which has a general form of Code:
(type-to-cast-to) (expression-to-cast) Just like you can cast a real expression to an integer expression by saying (int)(3.14159), you can cast pointer-to-function expressions. The thing is that not all function pointers are alike; some pointers point to a function that takes an int as an argument, others point to a function that returns a double, etc, etc. They're all different, because the functions' declarations are different. Hence, when you've defined a function (qsorty in this case) that expects as its third parameter a pointer to a function that takes two pointer-to-void arguments, and you call it with its third argument being a pointer to a function that takes two pointer-to-char arguments (strcmp, for example), then you'll get a warning (if not error) saying that the types don't match. That's why you have to perform a type cast. Quote:
Again, that would be due to the type cast ![]() |
|
#5
|
|||
|
|||
|
ok i think i've got it. thanks-a-lot for your explenation analyser
![]() |
|
#6
|
||||
|
||||
|
You're quite welcome
![]() |
![]() |
| Viewing: Dev Shed Forums > Programming Languages > C Programming > function pointer stuff |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|