They're called Exit codes
It is a status or execution code that your program returns. It's somewhat legacy these days, but in general it is meant to let the caller know how the execution went.
Zero typically means successful execution.
Just as a function in your code returns a value to it's caller, so should your program return a value to its caller, like a script, or the operating system.
Return codes is a relic from the past, but is still used in some cases, like console applications, because it is simple and easy to handle.
Why should you use one over the other?
If you have no intention of returning an error code, C# has added the syntactic sugar of allowing void, so you don't need to think about returning anything. And in most cases, this is fine.
But if you are developing a console application, and you want to let the caller handle any results from your code, return codes are an easy and standardized way to do this.
static int Main(string[] args) { return 0; } // Everything went fine
static int Main(string[] args) { return -1; } // An error occured.
static int Main(string[] args) { return 2; } // Program completed, with warnings.
static void Main(string[] args) { } // Just returns zero.
What the codes mean is up to each program, and would be documented in the documentation or similar.
See this answer for how it can be used in bat files:
Example .bat file
@echo off
myprogram.exe
if errorlevel 1 (
echo Failure Reason Given is %errorlevel%
exit /b %errorlevel%
)