Allora... hai ragione sul fatto di dover operare su ogni singolo carettere della stringa, e hai ragione sul fatto che 48 = 30h (indipendentemente da assembly), però ancora non hai chiarito che cos'è per te il "valore numerico di una lettera"! E' il codice ASCII corrispondente? In questo caso, perché togliere 48, che corrisponde al carattere 0? Vedi
questa tabella.
Se vuoi il codice ASCII di una lettera, ti basta fare il cast a int. Invece se vuoi la corrispondenza
a = 1 perché è la prima lettera
b = 2 perché è la seconda
c = 3 ...
...
allora puoi sottrarre 'a' e aggiungere uno, quindi
int numero = carattere - 'a' + 1;
In ogni caso, io cercherei di evitare i cosiddetti "magic number", cioè quei numeri (come il tuo 48) che uno trova nel codice e non sa bene da dove vengono. Se proprio devi, usa '0'. Il motivo, oltre che di comprensibilità del codice, è che diverse macchine potrebbero usare diverse tabelle ASCII...