You can do this by simply specifying a block in a macro or using a variable macro, as suggested in another answer. However, I would not recommend using macros for this purpose, since it usually makes the code less readable, more error prone and harder to read / maintain.
Instead, for general programming, consider using function pointers corresponding to the desired functionality.
Another option is to use the C11 _Generic macro to create safe, generic type code. Example:
#include <stdio.h> #include <ctype.h> void int_increase (int* item) { (*item)++; } void char_increase (char* item) { (*item)++; } void int_print (int* item) { printf("%d ", *item); } void char_print (char* item) { printf("%c", *item); } void int_clear (int* item) { *item = 0; } void char_clear (char* item) { *item = '\0'; } void int_traverse (int* data, size_t size, void(*action)(int*)) { for(size_t i=0; i<size; i++) { action(&data[i]); } } void char_traverse (char* data, size_t size, void(*action)(char*)) { for(size_t i=0; i<size; i++) { action(&data[i]); } } #define do_something(data, size, action) \ _Generic((data), int* : int_traverse, \ char* : char_traverse) \ ( (data), (size), _Generic((data), int*: int_ ## action , char*: char_ ## action ) ) int main (void) { int int_data [] = {1, 2, 3, 4, 5}; do_something(int_data, 5, increase); do_something(int_data, 5, print); printf("\n"); do_something(int_data, 5, clear); do_something(int_data, 5, print); printf("\n"); char char_data [] = "ABCDE"; do_something(char_data, 5, increase); do_something(char_data, 5, print); printf("\n"); do_something(char_data, 5, clear); do_something(char_data, 5, print); printf("\n"); return 0; }
Output:
2 3 4 5 6 0 0 0 0 0 BCDEF
Just add more similar features if you need to use other types.