Skip to content

Latest commit

 

History

History

0x0F-function_pointers

0x0F. C - Function pointers

In C, like normal data pointers (int *, char *, etc), we can have pointers to functions. Following is a simple example that shows declaration and function call using function pointer.

#include <stdio.h>
// A normal function with an int parameter
// and void return type
void fun(int a)
{
    printf("Value of a is %d\n", a);
}
  
int main()
{
    // fun_ptr is a pointer to function fun() 
    void (*fun_ptr)(int) = &fun;
  
    /* The above line is equivalent of following two
       void (*fun_ptr)(int);
       fun_ptr = &fun; 
    */
  
    // Invoking fun() using fun_ptr
    (*fun_ptr)(10);
  
    return 0;
}

Output:

Value of a is 10

Why do we need an extra bracket around function pointers like fun_ptr in above example?
If we remove bracket, then the expression “void (*fun_ptr)(int)” becomes “void *fun_ptr(int)” which is declaration of a function that returns void pointer. See following post for details.

Resources

Read or watch:

Tasks

0. What's my name

Write a function that prints a name.

  • Prototype: void print_name(char *name, void (*f)(char *));

solution

1. If you spend too much time thinking about a thing, you'll never get it done

Write a function that executes a function given as a parameter on each element of an array.

  • Prototype: void array_iterator(int *array, size_t size, void (*action)(int));
  • where size is the size of the array
  • and action is a pointer to the function you need to use

solution

2. To hell with circumstances; I create opportunities

Write a function that searches for an integer.

  • Prototype: int int_index(int *array, int size, int (*cmp)(int));
  • where size is the number of elements in the array array
  • cmp is a pointer to the function to be used to compare values
  • int_index returns the index of the first element for which the cmp function does not return 0
  • If no element matches, return -1
  • If size <= 0, return -1

solution

3. A goal is not always meant to be reached, it often serves simply as something to aim at

Write a program that performs simple operations.

  • You are allowed to use the standard library
  • Usage: calc num1 operator num2
  • You can assume num1 and num2 are integers, so use the atoi function to convert them from the string input to int
  • operator is one of the following:
    • +: addition
    • -: subtraction
    • *: multiplication
    • /: division
    • %: modulo
  • The program prints the result of the operation, followed by a new line
  • You can assume that the result of all operations can be stored in an int
  • if the number of arguments is wrong, print Error, followed by a new line, and exit with the status 98
  • if the operator is none of the above, print Error, followed by a new line, and exit with the status 99
  • if the user tries to divide (/ or %) by 0, print Error, followed by a new line, and exit with the status 100

This task requires that you create four different files.

3-calc.h

This file should contain all the function prototypes and data structures used by the program. You can use this structure:

/**
 * struct op - Struct op
 *
 * @op: The operator
 * @f: The function associated
 */
typedef struct op
{
    char *op;
    int (*f)(int a, int b);
} op_t;

3-op_functions.c

This file should contain the 5 following functions (not more):

  • op_add: returns the sum of a and b. Prototype: int op_add(int a, int b);
  • op_sub: returns the difference of a and b. Prototype: int op_sub(int a, int b);
  • op_mul: returns the product of a and b. Prototype: int op_mul(int a, int b);
  • op_div: returns the result of the division of a by b. Prototype: int op_div(int a, int b);
  • op_mod: returns the remainder of the division of a by b. Prototype: int op_mod(int a, int b);

3-get_op_func.c

This file should contain the function that selects the correct function to perform the operation asked by the user. You’re not allowed to declare any other function.

  • Prototype: int (*get_op_func(char *s))(int, int);
  • where s is the operator passed as argument to the program
  • This function returns a pointer to the function that corresponds to the operator given as a parameter. Example: get_op_func("+") should return a pointer to the function op_add
  • You are not allowed to use switch statements
  • You are not allowed to use for or do ... while loops
  • You are not allowed to use goto
  • You are not allowed to use else
  • You are not allowed to use more than one if statement in your code
  • You are not allowed to use more than one while loop in your code
  • If s does not match any of the 5 expected operators (+-*/%), return NULL
  • You are only allowed to declare these two variables in this function:
    op_t ops[] = {
        {"+", op_add},
        {"-", op_sub},
        {"*", op_mul},
        {"/", op_div},
        {"%", op_mod},
        {NULL, NULL}
    };
    int i;

3-main.c

This file should contain your main function only.

  • You are not allowed to code any other function than main in this file
  • You are not allowed to directly call op_addop_subop_mulop_div or op_mod from the main function
  • You have to use atoi to convert arguments to int
  • You are not allowed to use any kind of loop
  • You are allowed to use a maximum of 3 if statements

Compilation and examples

julien@ubuntu:~/0x0e. Function pointers$ gcc -Wall -pedantic -Werror -Wextra -std=gnu89 3-main.c 3-op_functions.c 3-get_op_func.c -o calc
julien@ubuntu:~/0x0e. Function pointers$ ./calc 1 + 1
2
julien@ubuntu:~/0x0e. Function pointers$ ./calc 97 + 1
98
julien@ubuntu:~/0x0e. Function pointers$ ./calc 1024 / 10
102
julien@ubuntu:~/0x0e. Function pointers$ ./calc 1024 '*' 98
100352
julien@ubuntu:~/0x0e. Function pointers$ ./calc 1024 '\*' 98
Error
julien@ubuntu:~/0x0e. Function pointers$ ./calc 1024 - 98
926
julien@ubuntu:~/0x0e. Function pointers$ ./calc 1024 '%' 98
44
julien@ubuntu:~/0x0e. Function pointers$ 
Files

4. Most hackers are young because young people tend to be adaptable. As long as you remain adaptable, you can always be a good hacker

Write a program that prints the opcodes of its own main function.

  • Usage: ./main number_of_bytes
  • Output format:
    • the opcodes should be printed in hexadecimal, lowercase
    • each opcode is two char long
    • listing ends with a new line
    • see example
  • You are allowed to use printf and atoi
  • You have to use atoi to convert the argument to an int
  • If the number of argument is not the correct one, print Error, followed by a new line, and exit with the status 1
  • If the number of bytes is negative, print Error, followed by a new line, and exit with the status 2
  • You do not have to compile with any flags

Note: if you want to translate your opcodes to assembly instructions, you can use, for instance udcli.

solution