- Don't use goto
- DON'T USE goto
- DON'T USE goto
Now assuming that you aren't actually intending to use goto but are just enquiring about the nature of a programming element.
In case 1, i is a static variable. It exists for the lifetime of the program, although it is only in scope inside the if statement block. Because it has program lifetime it is created and initialised before main is entered so when you jump to the print statement i already has the correct value.
In listing 2 i is not static, it is automatic and has lifetime of the block that contains it. The goto skips the statement that initialises it and you get a garbage value. Since it is accessing a possibly non-existent automatic variable that has not been initialised this is undefined behaviour and so should be avoided.
In listing 3 the if statement is executed before the goto (and since 1 is true the block is executed). This initialises the memory used by i. However Strictly i only has lifetime of its containing block so when the goto statement alters the execution path back to the print statement i does not strictly exist although the printf access the same bit of memory that has already been initialised so it appears to print the correct value but is in fact undefined behaviour. Additionally since the goto jumps back up the code an infinite loop happens because nothing ever moves the follow of execution past the goto on line 11 to the return on line 12.
And to answer your final question the flow of execution does reach the printf statements, that is precisely what the goto statements do, alter the flow of execution in a non-structured way to the label indicated.