11-2 変数の共有

この記事は約3分で読めます。

ソースファイルを分割することで関数を共有し、別のファイルから関数を呼び出せるようになりました。次は、変数を共有する方法を考えます。

main.c

#include <stdio.h>
#include "getnum.h"
int main(void){
	int a,b;
	getNum("a:整数を入力してください");
	a=num;
	getNum("a:整数を入力してください");
	b=num;
	printf("aとbのうち大きい数字は%d\n",a>b?a:b);
	return 0;
}

getnum.h

int num;
void getNum(const char *str);

getnum.c

#include <stdio.h>
int num;
void getNum(const char *str){
	puts(str);
	scanf("%d",&num);
}

実行結果

bcc32の場合

警告: パブリックシンボル_numがモジュールmain.objとgetnum.objの両方に定義されている
a:整数を入力してください
2
a:整数を入力してください
3
aとbのうち大きい数字は0

VS2022の場合

a:整数を入力してください
2
a:整数を入力してください
3
aとbのうち大きい数字は3

bccで実行すると、警告が表示され、入力した整数が反映されず0と表示されてしまいました。これは、ヘッダファイルgetnum.hとソースファイルgetnum.cの両方で同じ変数numを定義しているからです。変数の定義をどちらか片方のファイルでのみにすれば警告が表示されなくなります。しかしそれだと定義したファイルのみでしか変数を使うことができません。そこでextern宣言を使います。一方のファイルで変数を定義し、もう一方のファイルでその変数を宣言します。externはexternal(外部の)の略です。

C言語では同じ名前の変数や関数は複数回定義することはできませんが、extern宣言や関数のプロトタイプ宣言なら何回でもできます。

main.c

#include <stdio.h>
#include "getnum.h"
int main(void){
	int a,b;
	getNum("a:整数を入力してください");
	a=num;
	getNum("a:整数を入力してください");
	b=num;
	printf("aとbのうち大きい数字は%d\n",a>b?a:b);
	return 0;
}

getnum.h

extern int num;
void getNum(const char *str);

getnum.c

#include <stdio.h>
int num;
void getNum(const char *str){
	puts(str);
	scanf("%d",&num);
}

実行結果

bcc32の場合

a:整数を入力してください
2
a:整数を入力してください
3
aとbのうち大きい数字は3

まとめ

別のソースファイルで定義された変数を用いるには、extern宣言をする。

externをつけないと、変数の定義と宣言を同時に行ったことになる。

コメント