Bien, como decía Jack el Destripador: vayamos por partes.
Un entero (corto) en C se guarda en memoria con un solo byte de ocho bits, siendo el numero cero el byte con todos los bits a ceros y el número 255 ese mismo byte pero con todos los bits a unos.
0 (decimal) = 00000000 bits
Un carácter ASCII se representa también con un solo byte de ocho bits pero organizados según una tabla (que en cierto momento de la antigüedad mas remota, a un comité de expertos norteamericanos del norte se les ocurrió, y vaya usted a saber qué se habían fumado justo antes de entrar en su reunión
).
El caso es que tomaron la determinación de que al '0' (carácter) lo iban a representar mediante el número entero 48. Afortunadamente lo que se fumaron no debía de ser muy fuerte porque decidieron representar el '1' (carácter) con el número entero 49, y el '2' con el 50 ... etc. etc. etc. Por lo menos mantuvieron el orden:
'0' (carácter) = 48 decimal = 00110000 bits
'1' (carácter) = 49 decimal = 00110001 bits
'2' (carácter) = 50 decimal = 00110010 bits
...
Esto nos lleva a que cada byte (entero) de 0 a 9 se corresponde directamente con un ASCII tomado como entero de 48 a 57.
0 (decimal) = 48 (decimal)
1 (decimal) = 49 (decimal)
2 (decimal) = 50 (decimal)
...
9 (decimal) = 57 (decimal)
Así con número enteros del 0 al 9 la conversión es directa entre ellos:
ASCII de '0' = 0 decimal + 48
ASCII de '1' = 1 decimal + 48
ASCII de '2' = 2 decimal + 48
O en C de forma directa y para todos ellos:
ASCII = Decimal + 48;
A la vicecontra, viceversa, o al revés para que me se entienda podemos ver qué decimal representa cada ASCII (entre '0' y '9') con la conversión al revés:
Decimal = ASCII - 48;
Pero como además ocurre, acontece, o sucede que en lenguaje C es exactamente igual, similar o análogo escribir 48 que '0' ya que el compilador, que es un chico muy listo, sustituye nuestro '0' por su equivalente 48 podemos escribir nuestras dos conversiones de la forma:
ASCII = Decimal + '0';
Decimal = ASCII - '0';
Con un dígito todo está solucionado pero y ¿qué pasa con los números enteros de dos o más dígitos?
Pues que tenemos que repetir nuestra conversión tantas veces como potencias de diez aparezcan en nuestro número a convertir.
No olvidemos que lo que estamos intentando hacer es convertir un número entero, sea lo que sea eso, en la forma en que escribimos y leemos un número entero, o sea: empezando por la derecha las unidades, seguidas de las decenas (o sea otra unidad pero multiplicada por diez), seguida de las centenas (o sea otra unidad pero multiplicada por cien) ... etc etc etc.
Y la solución no está escrita en el viento (Bob Dylan, año 1966) sino en un par de funciones en C que hagan un bucle iterando dichas potencias de diez, en un sentido, dividiendo para convertir de entero a ASCII, y multiplicando en el contrario de ASCII a entero:
255 = 2 * 100 + 5 * 10 + 5 * 1 o sea que tenemos que convertir 2,5,5 y juntarlos todos en un string ó por el contrario "255" = '2'-'0' * 100 + '5'-'0' * 10 + '5'-'0' * 1 y sumarlos todos.
Y estas dos cosas escritas en C son mas o menos como sigue:
De entero a string:
char * int8_to_str(int8 num){
int8 temp=1;
int8 i,sign=0,cnt=0;
char c;
char s[10];
while(temp>0) {
temp=(num/10);
s[cnt]=(num%10)+'0';
cnt++;
num=temp;
}
for(i = 0;i<(int8)(cnt/2);i++) {
c=s[i];
s[i]=s[cnt-i-1];
s[cnt-i-1]=c;
}
s[cnt]='\0';
printf("IntToStr %u (%s)\r\n",num
,s
); return &s[0];
}
Y de string a entero:
int8 str_to_int8(char* s){
int8 ret=0,i,l,m=1;
for(i=l;i<255;i--){
ret+= m * (s[i]-'0');
m = m * 10;
} else break;
}
printf("StrToInt %s (%u)\r\n",s
,ret
); return ret;
}
Ahí tienes el porqué de las cosas.
Nota importante: La función int8_to_str la he escrito de cabeza sin compilarla, igual hay que retocarla para que funcione correctamente, aunque mi consejo es que uses la itoa() estándar del C y te dejas de problemas y de quebraderos de cabeza innecesarios y te va a funcionar perfectamente.
P.D.: Novelas, me salen verdaderas novelas.