That's why C is the way it is, for all the hate it gets. I've been teaching my son the beginnings of C now that he's proficient in JavaScript and Lua, but making sure that every step of the way, we jump from a concept he already understands, to a new but related concept, and how they're connected.
For example, when I explained signed and unsigned to him, since we already covered the concepts of groups of bits having 2^n possible values, he quickly understood that signed has just as many values as unsigned, but the upper half just become negative inverse of the lower half.
C evolved from actual needs, and the fact that it's still widely used today shows how incredibly well designed it was for practical but relatively general problem solving. The C committee's job is mostly just a matter of saying "no" to every new feature request, because C has proven to be versatile enough to work in an extremely diverse array of situations.
We've been using Lua's C API and the Win32 API[1] to make cool things, such as a primitive Love2d clone, and just last night he said "Wait, you're telling me this is the old way of programming Windows? It just makes so much sense and seems so well designed!" C isn't perfect, but if you start from where C started, and trace it until now, you'll learn all the reasons behind its decisions, and they make sense in practical situations.
Kind of like the difference between metric and imperial measurement systems. Metric makes sense in an isolated mathematical world (i.e. science), bu imperial units make sense when you're working with real physical objects (e.g. construction).
[1] http://laurencejackson.com/win32/