You are inspecting a byte, which contains 0x39. That it corresponds to “9” doesn’t matter at all to the compiler at all. If you were on a system that didn’t match “9” <=> 0x39 it would still replace those byte values.
Thanks! I’ll have to noodle this around a bit because it’s hard for me to understand. xD

I dunno if this helps, but this screenshot shows the memory view of a program with a string. The hex representation in the middle is what is actually stored in memory. Each pair is one byte/char, and that is what your input[n] <= 0x39 is comparing against.