As soon as you trigger the button to turn on the CPU it starts machine and loads operating system aka OS. OS then loads/wakes up the drivers/hardwares and check if everyone is fully awake or not if not it throws/displays error on screen and asks user to do something about it. OK! so after waking up everyone in system, OS is ready and running fine. Now suppose you write a program in c and presses the run button after building it, what run does is it loads your programme in memory, data segment, stack which is part of OS memory, the instructions are being sent to OS that this guy has some input and needs answer. OS system does the calculations (ALU) and sends it back to user. Now all this happens with OS level but user has this impression, that his programme is doing this, catch is OS too can fail sometimes, due to some interrupts, or some errors may occur, that time OS throws an error which is non zero value always. 0 for successful execution.
We know that main() is system declared but user defined function i.e. we define this function. so for OS the entry point is main() but internally whatever written inside main is being executed by OS only. if our main() returns 0 it means your execution is successful and failed otherwise.
That's the very reason we return value in main().
Hope you got your answer now! :)