All that said, you want to learn C. It's important to realize that C (and most other programming languages, for that matter) is separate from its implementations. In particular, it's an abstract machine
and that is what you write code for rather than for a computer. The distinction is important because although you likely use a compiler (i.e., something that translates programs from one language to another; e.g., C to assembly or machine code or even C to Java), all that C implementations are required to do is to respect the semantics of the language.
Assumptions like "a byte is 8 bits wide," "int is a 32-bit type," "dynamic allocation happens on a heap," or "memory is linear" might make sense for a particular C implementation but will lead to portability problems in the general case. In truth, C bytes are CHAR_BIT
bits wide, int
has a length of sizeof (int)
bytes and its representation can vary widely (it is aligned
on an alignof (int)
-byte boundary, its range is given by INT_MIN
, it can have padding bits, trap representations, its signedness is represented in one of three ways) and semantics in even more ways that I won't get into here, the data structures used for dynamically allocated storage are up to the implementation, and memory in C is really segmented
rather than flat.
The convention by which C compilers map C programs to a particular platform (the target ISA
, the calling convention
, type representations, the executable file format, etc.) is called an ABI. However, C implementations are not limited to compilers: they can also be interpreters (you may have heard of the terms compiled language
and scripting language
; these are really misnomers as they refer to a quality of implementations, not of the language proper). In the case of interpreters, even more of the usual assumptions are likely to break down.
The reason I'm throwing out all these details is not to scare you but to get the point across that C is its own (arcane) beast and that you should be aware of that if you are writing C rather than code for a particular C implementation. Someday, you may want to switch to a different implementation or even to a different platform. It's better to be forward-thinking than to have to go through the expensive process of developing almost from scratch.
Also, you noted that you're learning C from some online tutorials. I highly recommend you not do that for anything related to engineering. Tutorials are very limited in their scope, most often written by inexperienced people, and the worst part is that you end up thinking you've learned more than you have or may have even learned the wrong thing. You won't believe how much of the information out there is tainted. For instance, there's a very popular book called C: The Complete Reference
by Herbert Schildt, who even sat on the standards committee. It's a technical nightmare; he does not understand C at all and although it has led to some very negative reviews by other people on the committee and elsewhere, people still read it to this very day.
Although I haven't updated this page in a very long time, I've put down some books that I would wholeheartedly recommend to you on this page
. There are also a couple of books by P.J. Plauger that I meant to put on there but never got around to it.