Jcrew, firstly based on how you're phrasing your questions you certainly have noble aspirations and a keen interest to understand exactly what each line of code
means. I have to say this is a personal quality which the vast majority of students on my CompSci degree completely ignored. I commend you highly for this.
Secondly, I can't possibly begin to provide detailed answers to all the (very good) questions which have been raised thus far in this threat, however I hope that I can provide you some additional direction to complement what others (celegorm and root particularly) have already offered.
I'm just dealing with C/C++ here since that is what most interest appears to be in. And whilst learning Java first is probably easier as it abstracts a lot of technical concepts away from the programmer, this actually makes what you're trying to learn (how things really do what they do, and why the code is written the way it is) much harder and hence I strongly recommend you stick to C to begin with (not even C++ as this is a
much larger superset of C and you needn't worry about any of that until you're capable with C).
To that end, I cannot stress enough the importance of one single book (
http://books.cat-v.org/computer-sci...ge/The.C.Programming.Language.2nd.Edition.pdf for an online copy or
http://www.amazon.co.uk/The-Programming-Language-2nd-Edition/dp/0131103628 to purchase - MAKE SURE YOU GET THE SECOND EDITION (as per the links)!)
The above is literally
the book on the language, and explains practically every construct in minute detail. It is referred to as the C bible and is well known as 'K&R' after the authors who invented the language.
Disclaimer: I cannot guarantee that this is absolutely 100% correct on all technical details, having worked with C professionally over the last 7 years I have learnt that every week you 'learn' something which you thought you already knew!
So, some detail. Others covered the fact that '#' is a preprocessor directive. The preprocessor is one stage of the 'build process'.
Build process
Essentially to 'build' (make an artefact e.g. executable or library) your code, several passes are done. These transition from source the final artefact, i.e. .c -> .o -> .exe or .so or .a
Note: Whilst on Windows you'd get .exe and .dll, on linux and other platforms you'd get a blank extension (i.e. myprog vs. myprog.exe) and .so or .a for a shared library or static library, respectively.
1) First the preprocessor is invoked, this executes all #define statements and replaces wherever the named symbol occurs in your source code with the actual definition (apologies for not giving examples of all the things I'm talking about here, it's all in the book above though!).
As well as #define statements, the pre-processor also resolves all #include directives to ensure that any header files are present on the system (you should never include a .c/.cpp file unless you really know what you're doing and why you have to..). This is done because there is no point even starting to compile your own source code if the code upon which it depends isn't even found on your system.
For more information on this side of things, read about the 'Include Path' which needs to be set for your compiler to be able to find all the include files you want. It is very back practice to have absolute paths - or even long relative ones - in your source code as it makes portability and readability difficult.
The pre-processor probably does other things as well, but these are the most important two.
2) After the preprocessor has finished (assuming without errors) then the compiler is invoked. This where all
your source code is checked for syntax errors, this could be missing ';' between statements (a statement is a single specific instruction - I have used several keywords deliberately in this post as they are correct terminology, however I can't explain them all but you'll recognise them when you see them elsewhere), illegal use of reserved keywords (e.g. a variable called 'int') etc.
I italicised the '
your' in that section because the header files which you are 'including' via the #include directive
should have compiled objects already associated to them. However, if this is not the case then these too will be compiled.
3) After compilation (again assuming no errors), you get to the
linking/linker phase. This is the final stage of the build process. At this point you'll have a series of binary object files (typically 'mysourcefile.o') which relate to each of your source files, however you have no executable, or library artefact, which you can actually run or share with another application, respectively.
The Linker is a stage which combines all these independent objects into the desired output, like a executable program in the simplest examples. Many programmers (even those who've completed a degree and done 1-2 years professional experience) will fall foul of the infamous 'undefined reference' error message, which is commonly mis-described as a compiler error. In fact this is a linker error and basically means that an object which the linker is currently processing makes reference (calls/invokes) to a function which exists in one of the other objects, however the linker has not been told where this other object lives, and hence can't see the
definition which this
reference relates to.
Data Structures and Algorithms
Once you've understood these principles you can move on to more abstract constructs like Data Structures and Algorithms - this is the foundation of every program and a solid understanding of how and when to use what data structure (and associated algorithm) is the first and most important criteria when hiring any programmer. This is a language-agnostic skill and clearly demonstrates logic, creative problem-solving and provokes thought about what design decisions and user requirements will influence the functionality and performance of any program.
I won't go on any more, there should be more than enough there for anyone to digest in one go. I will leave you with one final thought though...
Debugging is your friend, you'll learn 10x more fixing a program that doesn't work vs. writing it 'correctly' (i.e. one which does what you want it to, not necessarily in the best way) first time around.
Hope that helps,
Michael.