例えばiをmain関数内でのみ定義した場合、iはmain関数内でのみ使用でき、他の関数で使用することはできません。
/* mainでのみiを定義 */
#include <stdio.h>
void sub(){
        /* subではiが定義されていないので、iを使用することはできない。 */
        puts("Sub");
}
int main(int argc, char* argv[]){
        /* iを定義 */
        int i = 1;
        sub():
        /* mainでiが定義されているので、main内ではiが使用可能 */
        printf("Main %d\n",i);
        return 0;
}
/* subでもiを定義 */
#include <stdio.h>
void sub(){
        /* iを定義 */
        int i = 2;
        /* subでもiが定義されているので、iを使用することができる。 */
        /* ただし、mainのiとsubのiは別物である。 */
        printf("Sub %d\n",i);
}
int main(int argc, char* argv[]){
        /* iを定義 */
        int i = 1;
        sub():
        /* mainでiが定義されているので、main内ではiが使用可能 */
        printf("Main %d\n",i);
        return 0;
}
これら、関数内で定義した、関数内でのみ有効な変数を局所変数(内部変数、ローカル変数)と呼びます。
一方、C言語では全ての関数で使用可能な変数を作成することができ、これを大域変数(外部変数、グローバル変数)と呼びます。大域変数の作成方法は簡単で、関数外で変数の定義をします。
#include <stdio.h>
int i = 1;
void sub(){
        /* iを使用することができる。 */
        printf("Sub %d\n",i);
}
int main(int argc, char* argv[]){
        sub():
        /* iが使用可能 */
        printf("Main %d\n",i);
        return 0;
}
/* 途中でiの値を変更する例 */
#include <stdio.h>
int i = 1;
void sub(){
        /* iを使用することができる。 */
        printf("Sub %d\n",i);
        /* iの値を変更 */
        i++;
}
int main(int argc, char* argv[]){
        sub():
        /* iが使用可能(iの値はsub()内で変更されている) */
        printf("Main %d\n",i);
        return 0;
}
また、大域変数と局所変数とで名前がかぶった場合、局所変数が優先されます。
#include <stdio.h>
int i = 1;
void sub(){
        /* iは大域変数 */
        printf("Sub %d\n",i);
        /* iの値を変更 */
        i++;
}
void sub2(int i){
        /* iは引数 */
        printf("Sub2 %d\n",i);
}
int main(int argc, char* argv[]){
        /* main内でiを定義 */
        int i = 2;
        sub():
        sub2(6);
        /* iは局所変数 */
        printf("Main %d\n",i);
        return 0;
}
大域変数はどの関数内でも使用できるため使い勝手がいいですが、どこからでも値の変更ができてしまい、乱用すると思わぬバグが発生することがあります。使用時にはその目的を明確にしておきましょう。