Home > Blockchain >  pointer to a function and callbacks
pointer to a function and callbacks

Time:04-21

I'm supposed to make function "print", print a value of "greatest" or "lowest function" depending on the user's choice

void print(int*walk,int*stop,int (*ptr)(int,int))
{
    for(walk; walk < stop; walk  )
    {
        printf("%d ",*walk);
    }

}

so this function here has to be somehow edited and I'm kind of lost. Pasting the rest of my code down below

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void print(int*walk,int*stop,int (*ptr)(int,int));
void randm(int*walk,int*stop,int p,int q);
int greatest(int*walk,int*stop);
int lowest(int*walk,int*stop);
int main()
{

    int N;
    printf("Pass number of arguments:");
    scanf("%d",&N);

    int *A =(int*)malloc(N*sizeof(int));


    randm(A,A N,10,15);
    print(A,A N,greatest(A,A N));


    free(A);
    return 0;
}
void print(int*walk,int*stop,int (*ptr)(int,int))
{
    for(walk; walk < stop; walk  )
    {
        printf("%d ",*walk);
    }

}
void randm(int*walk,int*stop,int p,int q)
{
    srand(time(NULL));
    for(walk; walk < stop; walk  )
    {
        *walk = rand()%q   p;
    }

}

int greatest(int*walk,int*stop)
{
    int value = *walk;
    for(walk 1; walk < stop; walk  )
    {
        if(*walk > value)
            value = *walk;
    }

    return value;
}
int lowest(int*walk,int*stop)
{
    int value = *walk;
    for(walk 1; walk < stop; walk  )
    {
        if(*walk < value)
            value = *walk;
    }
    return value;
}

edit. Instead of 2 functions "greatest", "lowest" I'm supposed to make one function that takes 3 arguments - pointer to the first element of the array, pointer to the end of the array, and 3rd argument which is int (*ptr)(int, int) - "greatest" or "lowest" Then I'm supposed to print it depending on the user's choice which would be print(A,A N,greatest(A,A N)); or print(A,A N,lowest(A,A N));

CodePudding user response:

To use print() to output the lowest or greatest by passing a function pointer, you simply call the function using the pointer within print(). In your example ptr is a pointer to a function returning int and taking two pointers-to int as its parameters. That matches the function declarations for lowest and greatest, e.g.

int greatest (int *walk, int *stop);
int lowest (int *walk, int *stop);

In order to use either in print() depending on which is called, you use ptr as the function name and use it like you would any other function. Here,

void print (int *walk, int *stop, int (*ptr)(int*,int*))
{
    printf ("%d\n", ptr(walk, stop));
}

(note: a '\n' has been used instead of following output with a space in the printf() format string - adjust as desired)

To then call print() to output the lowest and greatest values in your block of memory A, you would do:

    print (A, A N, lowest);       /* output lowest */

    print (A, A N, greatest);     /* output greatest */

Other Problems to Address

You have a number of other problems you should address. To use the time() function in srand() you should #include <time.h>. Secondly, srand (time(NULL)); is only called once in main(). There is no way to limit the number of calls to randm() to one. (i.e. it can be called more than once, not that it is).

You must validate EVERY user-input. If the user slips and enters 'r' instead of 5, your program fails to handle the invalid input and invokes Undefined Behavior in that case. Always validate user-input, e.g.

    if (scanf ("%d", &N) != 1) {  /* validate EVERY user-input */
        fputs ("error: invalid integer input.\n", stderr);
        return 1;
    }

Always validate EVERY memory allocation. When (not if) malloc() fails, it returns NULL. If you fail to catch the error and then derefererence the NULL pointer, Undefined Behavior (and likely a SegFault) results. You validate the allocation the same way you validate input, by checking the return value, e.g.

    int *A = malloc (N * sizeof *A);
    if (!A) {                     /* validate EVERY allocation */ 
        perror ("malloc-A");
        return 1;
    }

(note: In C, there is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc?)

Finally, while not an error (the preprocessor ignores whitespace), please space your code consistently to make your code much more readable (especially for older eyes). However you like is fine, as long as it is consistent and readable. Spacing your code a bit and putting everything above into a short example, you could do:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>

void print (int *walk, int *stop, int (*ptr)(int*,int*));
void randm (int *walk, int *stop, int p, int q);
int greatest (int *walk, int *stop);
int lowest (int *walk, int *stop);

int main (void) {

    int N = 0;
    
    fputs ("Pass number of arguments: ", stdout);
    if (scanf ("%d", &N) != 1) {  /* validate EVERY user-input */
        fputs ("error: invalid integer input.\n", stderr);
        return 1;
    }

    int *A = malloc (N * sizeof *A);
    if (!A) {                     /* validate EVERY allocation */ 
        perror ("malloc-A");
        return 1;
    }
    
    srand (time(NULL));           /* only called once in main() */
    
    randm (A, A N, 10, 15);
    
    fputs ("min : ", stdout);     /* prefix for minimum */
    print (A, A N, lowest);       /* output lowest */
    
    fputs ("min : ", stdout);     /* prefix for maximum */
    print (A, A N, greatest);     /* output greatest */

    free (A);
}

void print (int *walk, int *stop, int (*ptr)(int*,int*))
{
    printf ("%d\n", ptr(walk, stop));
}

void randm (int *walk, int *stop, int p, int q)
{
    for (; walk < stop; walk  ) {
        *walk = rand()%q   p;
    }

}

int greatest (int *walk, int *stop)
{
    int value = *walk  ;
    
    for (; walk < stop; walk  ) {
        if (*walk > value)
            value = *walk;
    }

    return value;
}

int lowest (int *walk, int *stop)
{
    int value = *walk  ;
    
    for (; walk < stop; walk  ) {
        if (*walk < value)
            value = *walk;
    }
    
    return value;
}

Example Use/Output

$ ./bin/walkstop
Pass number of arguments: 200
min : 10
min : 24
  •  Tags:  
  • c
  • Related