fork() returns twice. Once inside the parent process and once inside the child. In the parent it returns the PID of the child process and in the child process it returns 0. So by doing if(!fork()) any code that follows in the code block is executed by the child and the parent will continue after the if() code block.
When you call fork() it creates a copy of the running process, but as soon as you call one of the exec() family of functions it replaces the current process (the child in this case) with whatever program you tell it to. So you were on the right track. Very close
It's just not really a reservation. If you fork() and don't call an exec() function you'll have 2 copies of the original process running, but the child would start right after the fork() call, not at main().
Hope that explains it! Let me know if it still doesn't make sense.