0

Below is the code(unchanged) of a question I encountered while solving hackerrank questions:

But i couldnot understand 3 lines which i have marked as number 1,2 and 3 in the below code.

As the program flows from main to func's

Lets look at 3 first:

We are passing a function name lexicographic_sort as one of the parameter to string_sort function.

Now lets have a look at 1 and 2:

In function string_sort

lexicographic_sort is passed as int (cmp_func)(const char a, const char b)*

1st doubt: what is cmp_func, it is not defined anywhere, is it a sytem defined function?

2nd doubt: we are not passing any parameters which would go into char* a, char* b. What would go to their values?

    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <string.h>

 1. int lexicographic_sort(const char* a, const char* b) {

    }
    
    int lexicographic_sort_reverse(const char* a, const char* b) {
    
    }
    
    int sort_by_number_of_distinct_characters(const char* a, const char* b) {
        
    }
    
    int sort_by_length(const char* a, const char* b) {
    
    }

 2. void string_sort(char** arr,const int len,int (*cmp_func)(const char* a, const char* b))

    {
        
    
    }


    int main() 
    {
        int n;
    scanf("%d", &n);
  
    char** arr;
    arr = (char**)malloc(n * sizeof(char*));
  
    for(int i = 0; i < n; i++){
        *(arr + i) = malloc(1024 * sizeof(char));
        scanf("%s", *(arr + i));
        *(arr + i) = realloc(*(arr + i), strlen(*(arr + i)) + 1);
    }
  
    

 3. string_sort(arr, n, lexicographic_sort);

        for(int i = 0; i < n; i++)
            printf("%s\n", arr[i]);
        printf("\n");
    
        string_sort(arr, n, lexicographic_sort_reverse);
        for(int i = 0; i < n; i++)
            printf("%s\n", arr[i]); 
        printf("\n");
    
        string_sort(arr, n, sort_by_length);
        for(int i = 0; i < n; i++)
            printf("%s\n", arr[i]);    
        printf("\n");
    
        string_sort(arr, n, sort_by_number_of_distinct_characters);
        for(int i = 0; i < n; i++)
            printf("%s\n", arr[i]); 
        printf("\n");
    }
  • This code won't compile. – Robert Harvey Jul 06 '20 at 17:23
  • Hey Harvey, it is not complete code, It is a outline of Hacker rank's question using which we ll have to fill. But then I did not understand what they are passing in the lines 1, 2 and 3 – ravi chandra Jul 06 '20 at 17:28
  • `cmp_func` is the name of the 3rd parameter and its type is "pointer to a function which accepts two `char` pointers and returns `int`", just as `len` is the name of the 2nd parameter. – vgru Jul 06 '20 at 17:28
  • Hey Groo, Then what is char* a and char* b which is being passed to cmp_func? – ravi chandra Jul 06 '20 at 17:30
  • at code number 3, we are not passing any parameters with the function, so what values would a and b take? – ravi chandra Jul 06 '20 at 17:32
  • at 3, inside the string_sort(), you can call cmp_func() with whatever you want. Ergo, your question of what values a and b take is nonsensical. – vmt Jul 06 '20 at 17:36
  • understood, thank you a lot guy All of you – ravi chandra Jul 06 '20 at 17:44

3 Answers3

0

The function string_sort

void string_sort( char** arr, const int len, int (*cmp_func)(const char* a, const char* b) );

declared as having three parameters. The first one is of the type char **. The second one of the type const int. And the third one of the type int (*)(const char* a, const char* b) that is the third parameter is a pointer to function that has two parameters of the type const char * and the return type int. This parameter is used within the function string_sort to compare two strings.

Then the function string_sort is called like

string_sort( arr, n, lexicographic_sort );

where the third argument is the function lexicographic_sort_reverse declared like

int lexicographic_sort_reverse(const char* a, const char* b) {

}

that has the required type of the third parameter of the function string_sort. The function designator lexicographic_sort used as the third argument is implicitly converted to pointer to the function.

So

1st doubt: what is cmp_func, it is not defined anywhere, is it a sytem defined function?

cmp_func is the name pf the parameter of the function string_sort. In a function declaration that at the same time is a function definition names of parameters must be present.

The declaration of the function string_sort that is not a definition could look like

void string_sort( char**, const int, int ( * )(const char*, const char*));

That is names of parameters are not required.

You could imagine the function definition and its call the following way

string_sort(arr, n, lexicographic_sort);

//...

void string_sort( /*char** arr,const int len,int (*cmp_func)(const char* a, const char* b) */)
{
    char **arr1 = arr; // I changed the name of the parameter to arr1
    const int len = n;
    int (*cmp_func)(const char* a, const char* b) = lexicographic_sort;
    //...
}

2nd doubt: we are not passing any parameters which would go into char* a, char* b. What would go to their values?

It is the function string_sort calls within itself the function lexicographic_sort thyat was assigned to the parameter cmp_func passing to it strings pointed to by the parameter arr to compare them during sorting. You need to investigate the body of the function string_sort.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

1st doubt: what is cmp_func, it is not defined anywhere, is it a sytem defined function?

cmp_function is not a system function,It is a pointer to function in C, it is way to pass a function to another function (can be used as custom sort comparator as in this case or as callback in other use cases)

For the function void string_sort(char** arr,const int len,int (*cmp_func)(const char* a, const char* b))

It has 3 arguments:

arr: pointer to pointer to char

len: int

cmp_funct: pointer to function that has 2 arguments both are const char* and returns int.

so when you call string_sort you have to pass to it in third arguments a pointer to function(name of the function or & before it, it won't matter) that matches these arguments criteria as the case in int lexicographic_sort_reverse(const char* a, const char* b) and sort_by_number_of_distinct_characters.

2nd doubt: we are not passing any parameters which would go into char* a, char* b. What would go to their values?

I think this question is answered now, as they are not arguments to the function, they describe the arguments to the function pointer that is passed.

I really recommend that you read more about pointer to functions, there a lot of tutorials on it on the internet.

Mostafa
  • 468
  • 3
  • 16
0

The purpose of the string_sort function is to sort an array of strings in a particular order - exactly what that order is depends on the function designator that's passed as the third argument.

cmp_func is a pointer to a function - the declaration reads as

      cmp_func                                -- cmp_func
     *cmp_func                                --   is a pointer to
    (*cmp_func)(                            ) --   a function taking
    (*cmp_func)(            a               ) --     parameter a
    (*cmp_func)(          * a               ) --       is a pointer to
    (*cmp_func)(const char* a               ) --       const char
    (*cmp_func)(const char* a,             b) --     parameter b
    (*cmp_func)(const char* a,           * b) --       is a pointer to
    (*cmp_func)(const char* a, const char* b) --       const char
int (*cmp_func)(const char* a, const char* b) --   returning int

When you call string_sort, you pass a function designator as the third argument - in this case, the name of one of your comparison functions. string_sort then calls that function as part of its operation, and uses that to determine how to order the strings in the array.

This is probably best explained by example. Let's assume string_sort is implemented as a plain old bubble sort (in reality it probably wouldn't be, but it works for illustrative purposes):

void string_sort( char **arr, const int len, int (*cmp_func)(const char *a, const char *b ) )
{
  for ( int i = 0; i < len - 1; i++ )
  {
    for ( j = i+1; j < len; j++ )
    {
      if ( cmp_func( arr[i], arr[j] ) > 0 )
      {
        swap( &arr[i], &arr[j] ); // imagine this being implemented elsewhere
      }
    }
  }
}

The order in which strings are sorted depends on the comparison function pointed to by cmp_func. The normal protocol is that the comparison function will return a positive value if the first argument is "greater" than the second, a negative value if the first argument is "less" than the second, and 0 if the two values are "equal". We will swap strings if the first argument is "greater" than the second, otherwise we leave them as-is.

What "greater", "less", and "equal" mean depends on what function was passed to string_sort for cmp_func. Suppose arr[i] == "foo" and arr[j] == "bar". Here's how they would (likely) be ordered for each of the different comparison functions (based on the function names):

cmp_func                               Return value    String order
--------                               ------------    ------------
lexicographic_sort                               >0    "bar", "foo"
lexicographic_sort_reverse                       <0    "foo", "bar"
sort_by_number_of_distinct_characters            <0    "foo", "bar"
sort_by_length                                    0    "foo", "bar"
John Bode
  • 119,563
  • 19
  • 122
  • 198