extern

externについて整理する

externが着いた変数は、変数の型は認識されるが変数のための領域はメモリ上に確保されない。他のコンパイル単位で確保されているはずの領域を共有する。他のコンパイル単位にある関数もexternを付けてプロトタイプ宣言することで呼び出し可能になる

サンプル(素数を求めるプログラム)

ファイル一つ目。関数をexternを付けてプロトタイプ宣言している。

#include <stdio.h>

extern void count_primes(void);
extern void print_primes(void);

int max;
int count;
int primes[100000];

int main(void) {
    printf("上限値:");
    scanf("%d", &max);

    count_primes();
    print_primes();

    return 0;
}

ファイル二つ目。一つ目のファイルで宣言した変数をextern宣言する。

extern int max;
extern int count;
extern int primes[];

static int isprime(int n);

void count_primes(void) {
    int i;

    count = 0;
    for (i=2; i <= max; ++i) {
        if (isprime(i)) {
            primes[count++] = i;
        }
    }
}

static int isprime(int n) {
    int i;
    for (i=2; i < n; i++) {
        if ((n % i) == 0) {
            return 0;
        }
    }
    return 1;
}

ファイル三つ目。同じく一つ目ファイルの変数をextern宣言する。#include

extern int count;
extern int primes[];

void print_primes(void) {
    int i;

    for (i=0; i < count; i++) {
        if (i > 0 && (i %10) == 0) {
            printf("\n");
        }
        printf( " %6d", primes[i]);
    }

    printf("\n素数の数 %d 個\n", count);
}

感想
自分はJavaでプログラムを始めたからexternは不思議な感じがする。変数がどこで宣言されているか分かりにくくなってしまう気がする。確かに一部のファイルだけ再コンパイルしてリンクすればよいので便利だけど。
もっとCを勉強していけば良い書き方が分かってくるのだろう。