The predicate char_code is a relation that defines the equivalence between a character and its ASCII code. For example, char_code(a, 96) is true since 96 is the decimal ASCII code for the character 'a'. If you were, for example, to query, char_code(C, 96) you would get C = a as a solution. Similarly, char_code('9', 57) is true since 57 is the ASCII code for the character that that represents the number 9. Note that '9' here is not a numeric 9, but the character '9'.
In your code, you are applying the char_code/2 predicate to a raw number. So char_code(C, 9) will succeed if C is the character code whose ASCII value is the number 9 (in this case, a horizontal tab). When you apply this and then attempt to use number_codes/2 on the values, you don't get digits since you aren't providing the ASCII codes corresponding to the digits.
You could see this if you were to do a simple test on your test/2 predicate at the Prolog prompt:
?- test([4,8,0], L).
L = ['\004\', '\b', '\000\']
What you expected was L = ['4', '8', '0'].
What you need to use is atom_number/2 and not char_code/2. Then you have atom_number(C, 9) succeeding when C = '9' (C is bound to the atom '9'):
numbers_atoms([],[]).
numbers_atoms([X|Y],[C|K]) :-
atom_number(C, X),
numbers_atoms(Y,K).
digits_number(Digits, Number) :-
numbers_atoms(Digits, Atoms),
number_codes(Number, Atoms).
Then you get:
?- digits_number([4,8,0], Number).
Number = 480.
You can also write:
numbers_atoms(Numbers, Atoms) :-
maplist(atom_number, Atoms, Numbers).