Secondo me diventa tutto chiaro se immagini di avere delle parentesi aggiuntive che "esplicitano" il senso, tipo...
if( (parola[i]) == ('a'||'b') ) {
/* fai questo e quello */
}
Nel secondo caso diventerebbe...
if( (parola[i]=='a') || (parola[i]=='b') ) {
/* fai questo e quello */
}
La prima formulazione verifica se 'a' è vero o 'b' è vero (cioè, in pratica, se 'a' è diverso da zero o 'b' è diverso da zero).
Siccome, secondo ASCII, 'a' è una costante che equivale numericamente a 97 e 'b' è una costante che equivale numericamente a 98 e tenendo presente che in C dire "falso" è un po' come dire "zero", la condizione 'a'||'b' è sempre vera.
Se provi a fare una verifica, ti accorgi che una condizione vera viene automaticamente "tradotta" nel valore numerico 1. Ne deriva che if(parola
=='a'||'b') è vero solo se parola è 1.
Dal momento che, secondo ASCII, nessuna lettera dell'alfabeto equivale a 1 e che nel tuo programma parti dal presupposto che l'array parola contenga solo lettere dell'alfabeto, if(parola=='a'||'b') è sempre falso.
La seconda formulazione agisce in modo del tutto diverso, verificando direttamente se nell'elemento i dell'array si trova 'a' o 'b', il che nel caso del tuo programma chiaramente può accadere o non accadere, dando come esito vero o falso a seconda delle situazioni.
Tutto questo è implicito nella risposta di Oregon.
Spero di averti aiutato, così come altri hanno aiutato me in passato. Se sapevi già queste cose, meglio ancora.