Puoi implementare la tua funzione reverse() in modo che riceva due puntatori, uno al carattere iniziale della sottostringa e uno al suo carattere finale.
Nel chiamare la funzione dal main() puoi usare una di queste due notazioni, che sono equivalenti:
reverse( s+i, s+j );
reverse( &s, &s[j] );
Supponendo che la stringa s che vuoi elaborare sia davvero "cambalus" e che i e j siano davvero 4 e 6, con entrambe le chiamate invii a reverse() un puntatore al V carattere di s ('a') e con s+j invii a reverse() un puntatore al VII carattere di s ('u'). Questo perché, dal momento che l'indicizzazione è zero based, s+4 equivale all'indirizzo di s[4] e s+6 equivale all'indirizzo di s[6].
Ipotizziamo che in reverse() tu chiami i due parametri pi (puntatore all'inizio) e pf (puntatore alla fine)... il "trucco" consiste nello scambiare i caratteri puntati da pi e da pf, incrementando uno e riducendo l'altro fino a quando i due puntatori non si "scontrano" o non si "incrociano"; in altre parole, il punto finale della sottostringa (pf) deve rimanere successivo al suo punto iniziale (pi), ovvero pf > pi.
Usando un ciclo while, avrai while( pf > pi ), all'interno del quale scambierai ripetutamente il contenuto della memoria puntata da pi con quella della memoria puntata da pf, avendo cura ad ogni ripetizione del ciclo di incrementare il puntatore pi e ridurre il puntatore pf, magari usando gli operatori ++ e --.