return will have the function output the value that is given after the return statement. This is useful when the function is used in the context y = Function(x), among other things. The return has to be of the same type as the function, else there will be an error.
We usually set main() to return a type int because we can then use the return as an error code, among other things. Void is also used to remove the return altogether. But if the type isn't void, then there has to be a return in the function, and all possibilities in the function in the end have to end in a return.
Returning zero is basically a statement to the outside world from the main function "Everything's fine!". It's an unwritten convention, I believe, though I may be wrong.