>>11
変数が静的かどうかにもよるが、>>11の例について内部的な違いについていえば、

前者はまず初期値なしの変数を定義する。コンパイラによっては変数を管理する
データに「この変数は値が不定である」という印をつける。その後、代入を行う
式を評価する。コンパイラによっては、この時先ほど付けた印を「この変数は
定数が代入されている。その値は 3 である」と書き換える。
コンパイラによっては他にもいろいろやっているだろう。

# この印は、
# int num;
# if (num == 1) ...
# num = 3;
# のような、代入をしていないのに値を参照しているといったバグを見つけ出して
# 警告メッセージを表示するのに使ったりする。

後者は初期値ありの変数を定義している。同時にコンパイラによっては
「この変数は定数が代入されている。その値は 3 である」という印をつける。

「定義+代入」と「初期値ありの定義」の違いがよく分かるのは以下のような
場合だと思う。

char a1[] = "abc";
char a2[2] = { 'a', 'b' };
char x1[]; x1 = "xyz";     /* これは不可 */
char x2[]; strcpy (x2, "xyz"); /* これも不可 */
char x3[2]; x3 = { 'a', 'b' }; /* 同じく不可 */