0
votes

Lets say I have a struct called Student.

typedef struct student {
    int age;
    char name[10];
} Student;

And I have an array of pointers to Students.

Student *a[10];

I need to sort the array by the names of the students. So I wrote the comparison function:

int compare(const void *a, const void *b){
    Student *temp1=*(Student **)a;
    Student *temp2=*(Student **)b;
    return strcmp(temp1->name, temp2->name);
}

Then I have the function to sort:

void SortArray(Student *a[], int len){
    qsort(a, len, sizeof(Student *), *compare*);
    printArray(a);
}

The last part of the qsort is what I don't get. I saw some posts where they wrote &compare, and some where they don't. Only when I used &compare it worked.
How do I know whether to use & or not?

2
Functions are similar to arrays in one way: If the function is used when a pointer to a function, it will decay to a pointer. It's usually safe to use e.g. compare only, but I recommend you use &compare to make it more explicit for the readers of the code. - Some programmer dude
You don't need any decoration, just pass compare. - Amit
&compare is explicit/readable in exactly the same way &array[0] is: confusing and gratuitously ugly to anyone who knows the language. Just use compare or array. Note that every time you call a function, as in func(x), the name func is decaying to a pointer because the () operator (function call) requires a function pointer as its operand. - R.. GitHub STOP HELPING ICE

2 Answers

1
votes

As the name of the function referenced to the function, you can use the name of the function. Also, as mentioned in comments, & is ok to reference too.

1
votes

Did you try to call the function like for example:)

qsort(a, len, sizeof(Student *), ***********compare);

or like

qsort(a, len, sizeof(Student *), &***********compare);

According to the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

4 A function designator is an expression that has function type. Except when it is the operand of the sizeof operator65) or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.

So in this expression

***********compare

the function designator compare is implicitly converted to function pointer then applying the dereferencing it is in turn converted to the function type and then again to function pointer and so on.

Of course you can explicitly specify &compare though it is not necessary.

Here is a demonstrative program

#include <stdio.h>

void f(void)
{
    puts("Hello eitanmayer");
}

void g(void f(void))
{
    f();
}

int main( void )
{
    g(&******f);
}

Its output is

Hello eitanmayer

So the problem with your code can be somewhere else.