You can do this in standard C using designated initializers:
int (*tab[256])(uint8_t *data, int *datalen) = {
[0x10] = fun_a_1,
fun_a_2,
fun_a_3,
...
fun_a_n,
[0x90] = fun_b_1,
fun_b_2,
fun_b_3,
...
};
The syntax [n] = x sets the n'th element of the array to the given value. We use this to set the first of the non-NULL elements in a group. Subsequent initializers are then set in order after the the given object, so you don't need to explicitly specify the index for each one. We can also take advantage of the fact that array elements not explicitly initialized are set to NULL.
So in the above example, element 0x10 is explicitly set to the first function pointer. The next object in the initializer list then applies to element 0x11, the next to 0x12 and so forth.
While some compilers may support a range of initializers as an extension, i.e. [ 0 ... 9 ], the above does not depend on such extensions and is conforming to the C standard.
array_index = (id < 0x20) ? (id - 0x10) : (id - 0x80).