The last parameter of this line in main()
makes me lost
// declaration
void qsort(char *linep[], int left, int right, int (*compare)(void *, void*);
// use
main(){
qsort((void**) lineptr, 0, nlines-1, (int (*)(void*,void*))(numeric ?
numcmp : strcmp));
}
I understand the ternary operator but let's say numeric == 0 then what does this mean?
(int (*)(void *, void*))strcmp;
Do datatypes of function parameters mismatch?
int strcmp(const char*, const char*);
void qsort( , , , int(*)(void*)(void*);
Can I typecast a function pointer?
Line. A line is a collection of idols within a K-pop group who all have something in common. For example, the dance line is a group's dancers, the maknae line is its younger members, and the '00 line is all of its members who were born in 2000.
Sasaeng: This word is usually followed by fan as in "sasaeng fan," or super obsessed fans who go a little bit over the top in expressing their love for their favorite idols.
K-pop stands for Korean pop, pop being short for pop music. The name for the genre is first recorded in English around 1990–95. Strongly influenced by Western popular music, K-pop took off in 1992 with Seo Taiji and Boys, who incorporated rap, rock, and dance elements into Korean popular music.
Your bias is your favourite member of a group; your bias group is your favourite group. Related: ult bias - your absolute favourite member of all idol groups; bias wrecker: a member of a group that makes you want to switch from your current favourite in that group.
In your code, using the cast
(int (*)(void *, void*))strcmp;
means, strcmp()
is a function pointer, which takes two void *
arguments and returns an int
.
Usually, for function pointers, casting is a very bad idea, as quoting from C11
, chapter §6.3.2.3
[...] If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.
but, in your case, for the argument types, char *
and void *
alias each other, so the typecasted type is compatible with the actual effective type(s), so (at a later point) the function call is defined.
Yes, you can cast a function pointer to a pointer to a function with a different signature. Depending on your calling convention (who cleans the stack up? The caller or the callee?) calling that function will be bad if there is a different number of arguments or their sizes differ.
Neither is the case here: On your standard architecture (sun workstations, Linux PCs, raspberry PI) the argument pointers to different data types are represented identically so that no harm is expected. The function will read the 4 or 8 byte value from the stack and interpret the memory pointed to as data of the expected type (which it should have though, e.g. don't use a float compare function on strings; it may throw because arbitrary bit patterns can be NaNs etc.).
I wanted to alert you to the fact that today's standard lib's qsort
has a different function signature (and semantic) than K&R's example. Today's qsort
gets a pointer to the beginning of an element vector and calls the compare function with pointers to the elements in the array; in the case of an array of string pointers, the arguments are pointers to pointers which are not suitable for strcmp()
. The arguments have to be dereferenced first. The linux man page for qsort has an example for a strcmp
wrapper which does just that. (The man page web export appears somewhat garbled, but is still readable.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With