Last active
June 14, 2023 10:26
-
-
Save savaged/f9313d23c97b383480988d73506bd761 to your computer and use it in GitHub Desktop.
Fun with function pointers in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Program.h | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
typedef int (*op_on_triple_ptr)(int, int, int); | |
typedef int (*op_on_pair_ptr)(int, int); | |
typedef int (*op_on_single_ptr)(int); | |
void cout_for_op(char* op_name, int op_result); | |
void cout_feedback_usage(); | |
int zero_on_triple(int a, int b, int c); | |
int mult_on_triple(int a, int b, int c); | |
int sum(int a, int b, int c); | |
int mean(int a, int b, int c); | |
int zero_on_pair(int a, int b); | |
int mult_on_pair(int a, int b); | |
int add(int a, int b); | |
int sub(int a, int b); | |
int zero_on_single(int a); | |
int inv(int a); | |
int incr(int a); | |
int decr(int a); | |
int do_op_on_triple(op_on_triple_ptr op, int x, int y, int z); | |
int do_op_on_pair(op_on_pair_ptr op, int x, int y); | |
int do_op_on_single(op_on_single_ptr op, int i); | |
op_on_triple_ptr get_op_on_triple_ptr(char* op_name); | |
op_on_pair_ptr get_op_on_pair_ptr(char* op_name); | |
op_on_single_ptr get_op_on_single_ptr(char* op_name); | |
// Program.c | |
#include "Program.h" | |
int main(int argc, char **argv) | |
{ | |
switch (argc) | |
{ | |
case 5: | |
cout_for_op(argv[4], do_op_on_triple(get_op_on_triple_ptr(argv[4]), atoi(argv[1]), atoi(argv[2]), atoi(argv[3]))); | |
break; | |
case 4: | |
cout_for_op(argv[3], do_op_on_pair(get_op_on_pair_ptr(argv[3]), atoi(argv[1]), atoi(argv[2]))); | |
break; | |
case 3: | |
cout_for_op(argv[2], do_op_on_single(get_op_on_single_ptr(argv[2]), atoi(argv[1]))); | |
break; | |
default: | |
cout_feedback_usage(); | |
return 1; | |
} | |
return 0; | |
} | |
void cout_for_op(char* op_name, int op_result) { printf("%s: %i%c", op_name, op_result, '\n'); } | |
void cout_feedback_usage() | |
{ | |
printf("Arguments: operand [operand] [operand] operation\n"); | |
printf(" where an operand is an integer and the operation is a short name for a math operation\n"); | |
printf(" like 'mult' (for multiply), sum, mean (average), add, sub (subtract), inv (invert),\n"); | |
printf(" incr (increment) and decr (decrement).\n"); | |
printf(" At least one operand and operation are required and two optional further operands.\n"); | |
printf(" E.g. 8 incr or 8 9 mult or 8 9 7 sum\n"); | |
} | |
int zero_on_triple(int a, int b, int c) { return 0; } | |
int mult_on_triple(int a, int b, int c) { return a * b * c; } | |
int sum(int a, int b, int c) { return a + b + c; } | |
int mean(int a, int b, int c) { return sum(a, b, c) / 3; } | |
int zero_on_pair(int a, int b) { return 0; } | |
int mult_on_pair(int a, int b) { return a * b; } | |
int add(int a, int b) { return a + b; } | |
int sub(int a, int b) { return a - b; } | |
int zero_on_single(int a) { return 0; } | |
int inv(int a) { return a * -1; } | |
int incr(int a) { return ++a; } | |
int decr(int a) { return --a; } | |
int do_op_on_triple(op_on_triple_ptr op, int x, int y, int z) { return op(x, y, z); } | |
int do_op_on_pair(op_on_pair_ptr op, int x, int y) { return op(x, y); } | |
int do_op_on_single(op_on_single_ptr op, int z) { return op(z); } | |
op_on_triple_ptr get_op_on_triple_ptr(char* op_name) | |
{ | |
if (strcmp(op_name, "mult") == 0) | |
return mult_on_triple; | |
if (strcmp(op_name, "sum") == 0) | |
return sum; | |
if (strcmp(op_name, "mean") == 0) | |
return mean; | |
return zero_on_triple; | |
} | |
op_on_pair_ptr get_op_on_pair_ptr(char* op_name) | |
{ | |
if (strcmp(op_name, "mult") == 0) | |
return mult_on_pair; | |
if (strcmp(op_name, "add") == 0) | |
return add; | |
if (strcmp(op_name, "sub") == 0) | |
return sub; | |
return zero_on_pair; | |
} | |
op_on_single_ptr get_op_on_single_ptr(char* op_name) | |
{ | |
if (strcmp(op_name, "inv") == 0) | |
return inv; | |
if (strcmp(op_name, "incr") == 0) | |
return incr; | |
if (strcmp(op_name, "decr") == 0) | |
return decr; | |
return zero_on_single; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Makefile