第11章 変数の通用範囲

教科書P182〜193

1 復習

変数は関数内で定義(宣言)し、関数内でのみ有効。

[例]

#include     <stdio.h>

/* プロトタイプ宣言 */
void sub(void);

void main(void)
{
    int a = 10;
    printf("main関数のa = %d\n", a);
    sub();
}

void sub(void)
{
    int a = 0;
    printf("sub関数のa = %d\n", a);
}
《実行結果》
main関数のa = 10
sub関数のa = 0

※main関数で宣言した変数aとsub関数で宣言した変数aは「別物」である!!

Q:main関数で宣言した変数aの値をsub関数で表示するには?

A:sub関数に引数として渡す

[解答例1]

#include     <stdio.h>

/* プロトタイプ宣言 */
void sub(int);

void main(void)
{
    int a = 10;
    printf("main関数のa = %d\n", a);
    sub(a);
}

void sub(int a)
{
    printf("sub関数のa = %d\n", a);
}
《実行結果》
main関数のa = 10
sub関数のa = 10

[解答例2]

#include     <stdio.h>

/* プロトタイプ宣言 */
void sub(int *);

void main(void)
{
    int a = 10;
    printf("main関数のa = %d\n", a);
    sub(&a);
}

void sub(int *a)
{
    printf("sub関数のa = %d\n", *a);
}
《実行結果》
main関数のa = 10
sub関数のa = 10

2 一度宣言した変数の値を保持する(静的変数)

関数内で宣言する変数の前にstaticを付けると、関数が終わっても開放されずに残るため、値を保持することができる。
この変数を静的変数と呼ぶ。

[例]

#include     <stdio.h>

/* プロトタイプ宣言 */
void sub(void);

void main(void)
{
    sub();
    sub();
    sub();
    sub();
    sub();
}

void sub(void)
{
    static int a = 0;
    a++;
    printf("a = %d\n", a);
}
《実行結果》
a = 1
a = 2
a = 3
a = 4
a = 5

[プログラムの流れ]

  1. 最初にsub関数が呼ばれると、メモリ内にint型の長さを持つ変数aの領域が確保され、初期値として0が格納される。
  2. sub関数終了時、通常の変数はメモリから開放されるが、変数aはstaticで宣言されているため、開放されずに残る。
  3. 2度目にsub関数が呼ばれると、変数aを宣言しようとするが、既にメモリ上に確保されてるため、何もしない
  4. プログラム終了時、全ての変数が開放される。

[注意]

静的変数として使う場合、変数宣言時に初期値を代入しなければならない。

#include     <stdio.h>

/* プロトタイプ宣言 */
void sub(void);

void main(void)
{
    sub();
    sub();
    sub();
    sub();
    sub();
}

void sub(void)
{
    static int a;
    a = 0;
    a++;
    printf("a = %d\n", a);
}
《実行結果》
a = 1
a = 1
a = 1
a = 1
a = 1

変数aの領域は確保されたままだが、関数が呼ばれるたびに0が代入されてしまう。

3 関数の外に変数を宣言する(グローバル変数)

変数は関数の外で定義(宣言)することができる。関数の外で宣言した変数は、そのソース内の全ての関数で使うことができる
この変数をグローバル変数と呼ぶ。

[例]

#include     <stdio.h>

/* グローバル変数 */
int a;

/* プロトタイプ宣言 */
void sub(void);

void main(void)
{
    a = 0;
    sub();
    printf("main関数から a = %d\n", a);
    sub();
}

void sub(void)
{
    a++;
    printf("sub関数から a = %d\n", a);
}
《実行結果》
sub関数から a = 1
main関数から a = 1
sub関数から a = 2

4 複数のソースで共通に使える変数を宣言する(外部変数)

C言語は複数のソースファイルを結合(リンク)して1つのプログラムを作ることができる。この際、複数のソースファイル内で共通に使う変数を宣言することができる
この変数を外部変数と呼ぶ。

[例]

《ソース1》
#include     <stdio.h>

/* 外部変数(元) */
int a;

/* 外部関数のプロトタイプ宣言 */
void sub(void);

void main(void)
{
    a = 0;
    sub();
    a += 10;
    printf("main関数で a = %d\n", a);
}
《ソース2》
#include     <stdio.h>

/* 外部変数 */
extern int a;

/* プロトタイプ宣言 */
void sub(void);

void sub(void)
{
    a = 10;
    printf("sub関数で a = %d\n", a);
}
《実行結果》
sub関数で a = 10
main関数で a = 20

[POINT]

  1. 外部変数は複数のソース内のどこか1箇所で宣言する。
  2. 宣言したソース以外のソースで利用する場合、externを付けて同じ名前の変数を宣言する。(Windowsのショートカットのようなイメージ)

5 複数のソースを使う場合のテクニック・1

複数のソースを組み合わせて1つのプログラムを作る場合、ソース内でのみ使う関数や変数、各ソース共通で使う関数や変数を区別するため、次のようにプログラミングすることが望ましい。

[例]

《ソース1》
#include     <stdio.h>

/* 外部変数(元) */
int a;

/* グローバル変数 */
static int b;

/* 外部関数のプロトタイプ宣言 */
void sub1(void);

/* プロトタイプ宣言 */
static void out(int);

void main(void)
{
    a = 0;
    sub1();
    a += 10;
    out(a);
}

static void out(int a)
{
    printf("%d", a);
}
《ソース2》
#include     <stdio.h>

/* 外部変数 */
extern int a;

/* プロトタイプ宣言 */
void sub1(void);
static void sub2(void);

void sub1(void)
{
    a = 10;
    printf("sub関数で a = %d\n", a);
}

static void sub2(void)
{
    ・
    ・
    ・
}

[POINT]

  1. ソース内でしか使わない関数、グローバル変数はstaticを付けて宣言する。
  2. ほかのソースでも使う関数(外部関数)、外部変数はそのまま宣言する。

[ TOP ]