These are questions that have come up while others learned C. They are here for your reference, feel free to submit a PR with additional questions (or to answer existing questions)!
This is one of those strange parts of C. For the most part, array syntax and pointer syntax can be used interchangeably. An array is just a sequence of values, one after the other, starting at some address. Each item is of the size its type (i.e. 1 byte for a char, 4 bytes for an int). C has no notion of how long the array is. You can access memory pass the size of the array, and C won't complain at all! This would be a IndexOutOfBounds exception in Java, but not C. C's the gun you can use to do amazing things, or to blow your foot clean off. Careful! Pointers reference some piece of memory with a specific type. Pointer arithmetic allows you to look at memory around that piece of memory. This is similar to indexing into an array. We try and stay away from pointer math where possible as it is ugly, and using array syntax is almost always the right thing.
There is one exception where arrays are different from pointers that has to do with statically allocated arrays, but we'll go into that much later.
I'm probably missing the intention of this question. Malloc is only used inside a function. Malloc is called anywhere a function can be called to allocate memory. That memory is just a sequence of bytes, and it is up to you as the programmer to use it correctly! When you malloc something, it is your job to track that memory so that it can later be deallocated. If the memory is returned from a function, then the caller must know that they must now track that memory and later free it.
.lib is not a thing. Never seen it.
.h files (header files) are used to define function prototypes (type signatures) so that they can be used in multiple .c files. You want to always ask yourself where a function is actually implemented (which .c file), and other .c files must include the .h file that defines the prototype. You can also define a special class of performance-sensitive functions in a .h file, and they can be included directly in any .c file that includes it. We can talk about what "static" and "inline" mean when used with functions later.
Further you must push, yes. Into the swamp of structured data, you must go.
structs are your mechanism in C to define a collection of data that always exists close to each other. Think of this like all of the data in an object. I could define a struct for a person that includes:
struct person {
int age, height, weight;
char *name;
};
All data you want to keep together. You can allocate it all (aside from the memory backing the ->name) with a single malloc.
Unions are much more confusing. You can only ever use a single one of the fields in the union at any point in time. For instance, if a union includes fields for GPA, and for salary:
union winning {
int salary;
double GPA;
};
A person will probably only have either a salary or a GPA, but both (very few people have a salary while in school). The union, then will allocate enough memory for only one of the fields, not both. You can only use the union as one of the fields that is appropriate to the person.
Long story short: unions are only there to save memory. They kind of suck.
http://i.imgur.com/WuKZd.gif ;-) Does not compute.
structures and unions are types at the same level as ints, chars, shorts, etc... structs can contain any of these types (including other structs). ints, shorts, etc, cannot contain other types -- that's the job of structs.
Because awesome.
Bitwise operators enable a lot of memory and information to be condensed into a very small amount of data. For instance, imagine a system that has a number of pieces (I'll call these pages) of memory. It wants to track if each of these is allocated. Lets say that these pages are 4096 bytes large. We could use an array of integers to track if these are allocated or not. 1 = allocated, 0 = not. A machine with 1GB of memory would require 2^30 / 2^12 = 2^18 = (1GB/4096) = 262K integers. Each int is 4 bytes, so we'd need 1MB just to do a pretty stupid and simple operation.
But what if we leveraged awesome? Now say use each bit in an array of ints to represent these allocated or not pages. Now we need 262k/32 = 8192 bytes. Easy-peasey.
They are most commonly used to store more data in values that you can fit into 32 bits.
Again: Why? Because you want to better use memory.