x is first declared as an int, and memory is allocated for x on the following line. No problems here.
No, that is not what happens. Inside a function, int x; defines x, which reserves memory for it. Then x = 4; stores a value in that memory.
extern int x;
x = 4;
extern int x; declares there to be an x but does not define it. If the program uses this x, it should define it somewhere else.
Outside a function, only declarations should appear. However, x = 4; is a statement, so it is not proper outside a function.
extern int x = 4;
This is valid C, but it is unconventional usage, so the compiler warns you. Conventionally, we write int x = 4; to define and initialize x, and we write extern int x; to declare x without defining it.
extern int x = 4; is defined by the standard; in this context, it is effectively the same as int x = 4;. But programmers generally do not use that form.
(If there is a visible prior declaration of x, such as static int x;, then extern int x = 4; does differ from int x = 4;. extern int x = 4; will refer to the x of the prior declaration, whereas int x = 4; will attempt to create a new x.)
extern int x;
int x = 4;
extern int x; declares x but does not define it.
int x = 4; defines x and initializes it.
Is case 3 the one and only way I should define external variables?
If you only need to use x in one translation unit, you can use int x = 4; by itself, without extern int x;. If you need to use x in multiple translation units, you should put extern int x; in a header file and include that header file in each source file that uses x, including the one that defines it.