First off I noticed a lot of C++ code and C code for that matter have strange defines like #ifndef, #ifdef, #define WIN32_LEAN_AND_MEAN etc etc, I have read that these are compiler defines, but how do these actually work?
what is the purpose of these defines? and how do these #defines actually change your code and change the way the compiler compiles your code?
secondly as I still consider myself a beginner++, when I read a lot of the standard template libraries code such as std::vector and other containers, they almost look cryptic to me, they contain a lot more #defines and other pre-processor jargon. The code looks nothing like if I was to create my own data structure, and the std:: code looks nothing like any of the code posted on here, is there a reason why the code looks so much different in the standard template library?
what is the purpose of these defines? and how do these #defines actually change your code and change the way the compiler compiles your code?
Simply put, as the preprocessor (not the compiler) processes an input file, it keeps symbol table to keep track of the existence and meaning of symbols. For example, the table might record that "_DEBUG" exists but has no value, and it might also record that "M_PI" exists and has the value "3.14159265".
The preprocessor goes through the file (more or less) line-by-line. When it encounters a #define directive, it adds the symbol in question to the table (if the symbol is already present it may warn or error out). When it encounters an #undef directive it removes the symbol from the table (if the symbol doesn't exist in the table it may warn or error out). When it encounters an #if it evaluates the condition using the symbol table and based on the result either includes or omits the contained block.
is there a reason why the code looks so much different in the standard template library?
When you write your code for yourself you're only solving your own problem. You know to fairly well-defined bounds what sort of inputs your program will need to deal with.
When a library developer writes code they're solving a problem for a large number of people. They must assume as little as possible the possible inputs, so necessarily the code becomes more complex. Compiler developers have an unusually complex task, as well, because their code should not break (that is, it should both compile and produce correct behavior) for all standard-compliant code. The standard library will be used by almost everyone who uses the compiler, so there's basically no bigger audience than that.
std::vector and other containers, they almost look cryptic to me
It's not that bad, you just have to learn to skip the bits that are irrelevant to your question.
Using your example, let's look at std::vector's and the question we'll ask is "what are the data members?"
There are three C++ standard libraries: GNU libstdc++, LLVM libc++, and Microsoft STL. All three are on github
template <class _Ty, class _Alloc = allocator<_Ty>>
class vector { // varying size array of values
/* skip a few lines */
_Compressed_pair<_Alty, _Scary_val> _Mypair;
pointer _Myfirst; // pointer to beginning of array
pointer _Mylast; // pointer to current end of sequence
pointer _Myend; // pointer to end of array
okay, vector is a bit scary, but look up a simple algorithm like std::fill or std::reverse and it's only a few lines in every library. Personally, I find LLVM libc++ to be the easiest read, since it is the newest and the least portable, they didn't have to complicate the code by too many special cases.