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.
Read or watch:
- Function Pointer in C
- Pointers to functions
- Function Pointers in C / C++
- why pointers to functions?
- Everything you need to know about pointers in C
Write a function that prints a name.
- Prototype:
void print_name(char *name, void (*f)(char *));
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
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 arrayarray
cmp
is a pointer to the function to be used to compare valuesint_index
returns the index of the first element for which thecmp
function does not return0
- If no element matches, return
-1
- If size <=
0
, return-1
Write a program that performs simple operations.
- You are allowed to use the standard library
- Usage:
calc num1 operator num2
- You can assume
num1
andnum2
are integers, so use theatoi
function to convert them from the string input toint
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 status98
- if the
operator
is none of the above, printError
, followed by a new line, and exit with the status99
- if the user tries to divide (
/
or%
) by0
, printError
, followed by a new line, and exit with the status100
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 ofa
andb
. Prototype:int op_add(int a, int b);
op_sub
: returns the difference ofa
andb
. Prototype:int op_sub(int a, int b);
op_mul
: returns the product ofa
andb
. Prototype:int op_mul(int a, int b);
op_div
: returns the result of the division ofa
byb
. Prototype:int op_div(int a, int b);
op_mod
: returns the remainder of the division ofa
byb
. 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 functionop_add
- You are not allowed to use
switch
statements - You are not allowed to use
for
ordo ... 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 (+
,-
,*
,/
,%
), returnNULL
- 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_add
,op_sub
,op_mul
,op_div
orop_mod
from themain
function - You have to use
atoi
to convert arguments toint
- 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$
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
andatoi
- You have to use
atoi
to convert the argument to anint
- If the number of argument is not the correct one, print
Error
, followed by a new line, and exit with the status1
- If the number of bytes is negative, print
Error
, followed by a new line, and exit with the status2
- 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.