Prima di tutto indenta meglio il codice:
void y (char *s, char *t){
int d,i=0,j,z=0;
for (; s[i] == t[i]; i++)
if (s[i] == '\0' || t[i] == '\0')
break;
for (j=i-1; j>i/2; j--){
d = s[j];
s[j] = s[z];
s[z] = d;
z++;
}
}
Poi spero che questo sia solo un esercizio, perché questa funzione è una vera bomba innescata.
L'aritmetica dei puntatori è relativamente semplice: se hai un puntatore ad un intero, questo altro non è che una variabile che contiene l'indirizzo in memoria di quell'intero. Aumentando di uno il puntatore, si va all'indirizzo successivo. Diminuendolo di uno, si va all'indirizzo precedente.Se si fanno le cose per bene, si possono anche fare somme/sottrazioni più grandi, ed anche moltiplicazioni. Sono quindi strumenti molto potenti, ma possono creare dei veri disastri, perché se non si controlla la posizione del puntatore (cioè in quale parte della memoria stiamo andando a scrivere/leggere), rischiamo il botto, cioè di andare in parti della memoria occupate da altre variabili.
Un utilizzo dei puntatori è quello di accedere agli elementi di un array. L'indirizzo dell'elemento 0 può essere assegnato ad una variabile puntatore, e valgono le seguenti equivalenze:
char *p; // puntatore ad un tipo char
p = &s[0]; // al puntatore p è assegnato l'indirizzo del primo elemento dell'array s
*p = 'c'; // equivale a s[0] = 'c';
p++; // avanza il puntatore all'elemento successivo dell'array
*p = 'i'; // equivale a s[1] = 'i';
Quindi per usare l'aritmetica dei puntatori nel tuo esempio:
void y (char *s, char *t){
int d; // sarebbe meglio char d
char *s1 = s;
char *t1 = t;
for (; *s1 == *t1; s1++, t1++)
if (*s1 == '\0' || *t1 == '\0')
break;
// Adesso prova a fare il resto (scambia l'ultimo elemento trovato di s con il primo elemento di t
// per metà della lunghezza della sotto-stringa trovata)