The difference is not only about where you set the variable, but about where you defined it as well.
Defined outside the function, it will have global scope and lifetime, meaning it is visible everywhere and it exists for the entire duration of the program. If you then place an initializer inside the function, whatever value it had just before function-entry will be replaced by the initializer value.
If you define it inside the function (and without a "static" specifier) it only exists while that function is executing, and is only visible to code inside the function. Because it only comes into existence when the function is entered, you must initialize it within the function, somehow.
If you define it inside the function, but with a static specifier,
static byte variable = 0;
then it will exist for the entire execution of the program but will only be visible to code within the function. In addition, an initializer on its definition (as opposed to other assignments to the variable) will only be executed once, just before the program begins executing, and will not be executed within function.
Using local and static (as opposed to global) variables is considered good program-variable hygiene because it hides those variables (to a greater or lesser degree) from code that needn't and shouldn't be able see or alter them.
loop()
, use egvoid loop() { static byte variable = 0; ...}