en fait getchar() te renvoit un caractère; même si l´utilisateur tape un chiffre, un chiffre est bien un caractère.
sachant que j est un int, que getchar() renvoi un char, il va y avoir un cast automatique de char à int;
or:
char caractere = " a";
printf("%c", caractere); / /affichera a
printf("%d", caractere); / /affichera la valeur ASCII de a, soit 97
revenons à ton exemple, le fait de faire j = getchar(); donnera à j le code ASCII du caractère entré, soit 54 pour 6 ( d´après http://asciitable.com ) . Si l´on affiche %c - j, ça affichera bien 6, mais sachant que j est un int, autant l´afficher en tant que tel, et donc afficher %d - j; ce qui aura pour action d´afficher la valeur ascii de 6, soit 54; pour y remédier, on enlève 48 à j, afin que j contienne bien 6, et non sa valeur ascii...
J´espère avoir été clair 