第11章でユーザ関数についての説明をしましたので、今度は関数間での変数の扱いについて説明したいと思います。
いわゆる「記憶クラス」というものなのですが、初心者にとってはわかりづらいものかもしれません。
このホームページでは分割コンパイルは扱わない予定になっておりますので、初心者がユーザ関数を同一ファイルで扱うときに必要となる記憶クラスのみを説明することにします。
「有効範囲」とはその変数を参照できる範囲のことです。 C言語では、変数の宣言をソースプログラムのどこに書くかによって「ローカル変数」と「グローバル変数」に分けられ、この有効範囲が異なってきます。
この有効範囲は「記憶クラス」と密接な関係がありますので、まずは有効範囲から理解してください。
※ 前章までの学習で使用していた変数はすべてこのローカル変数に該当します。
※ 仮にある関数のローカル変数にグローバル変数と同一の名前が存在するときには その関数内ではローカル変数が優先します。
※ main()の「a」 と goukei()の「a」はそれぞれの関数で宣言された「ローカル変数」です。 そのため、名前は同一でも別の変数となり、有効範囲も宣言された関数の中のみとなります。 ※ 「グローバル変数」はどの関数からも参照できるので、一見便利そうですが、変数の衝突が起こりやすく、 どこで変数の値が変えられるかわかりにくいため、安全性が低くくなります。 ですから、グローバル変数をあえて使うのは プログラム全体を統括する変数 プログラム全体の状況を記憶する変数 にとどめ、通常は「ローカル変数」を用いて、関数間でのやり取りは「引数」を使うようにしましょう。
「記憶クラス」とは宣言する変数をどこに記憶するかを指定します。
このホームページでは「自動変数」、「外部変数」、「静的変数」に分けて「記憶クラス」を説明します。
ただし、「auto」は通常省略され、単に「int a;」のように宣言する。
※ 前章までの学習で使用していた変数はすべてこの自動変数に該当します。
※ 個人的には外部変数も静的変数も明示的に初期化をしたほうがわかりやすいと思います。
「自動変数」は「ローカル変数」と、「外部変数」は「グローバル変数」と使用方法は同じですので、使用方法は「12-1. 有効範囲」を参照してください。
「静的変数」については、以下で説明します。
#include <stdio.h> int min1(int n); int min2(int n); int main(void) { printf("自動変数:最小値 = %d\n",min1(100)); printf("自動変数:最小値 = %d\n",min1(10)); printf("自動変数:最小値 = %d\n",min1(50)); printf("静的変数:最小値 = %d\n",min2(100)); printf("静的変数:最小値 = %d\n",min2(10)); printf("静的変数:最小値 = %d\n",min2(50)); return 0; } /*** 自動変数を使った例 ***/ int min1(int n) { /* min として自動変数を宣言 */ int min = 999; if (n < min) { min = n; /* min を更新 */ } return min; } /*** 静的変数を使った例 ***/ int min2(int n) { /* min として静的変数を宣言 */ static int min = 999; if (n < min) { min = n; /* min を更新 */ } return min; } |
min1()は自動変数を使って、 min2()は静的変数を使って、 引数の最小値を正しく保持できるかを比較する。 自動変数として宣言された「min」は、 min1()が実行されている間のみメモリ上に存在し、 関数が呼ばれるたびに 999 に設定される。 そのため、更新された最小値を記憶する事ができない。 静的変数として宣言された「min」は、 プログラムが実行している間はメモリ上に存在でき、 コンパイル時に一度だけ 999 に設定される。 そのため、更新された最小値を記憶する事ができる。 |
自動変数:最小値 = 100 --- 自動変数:最小値 = 10 | 値が保持できない 自動変数:最小値 = 50 --- 静的変数:最小値 = 100 --- 静的変数:最小値 = 10 | 値が保持できる 静的変数:最小値 = 10 ---
ご質問をいただきましたので、メモリ領域の例について説明します。
Cで扱うメモリ領域は一般に、プログラム領域、静的領域、スタック領域、ヒープ領域の 4つに大別されます。
「プログラム領域」には、プログラムを実行するためのプログラムコードが置かれます。
「静的領域」には、外部変数や静的変数が置かれます。
「スタック領域」には、自動変数が置かれます。 また、自動変数以外に、関数の引数や、関数の戻り値、長い計算式の一時変数などが置かれます。
「ヒープ領域」は、静的領域とスタック領域以外の第3のメモリ領域です。 malloc()などのメモリ割り当て関数を使ってメモリをプログラム中で動的に確保する場合には、このヒープ領域のメモリが割り当てられます。
ただし、メモリをどのように使うかは、C処理系により異なります。
「初心者のためのポイント学習C言語」 Copyright(c) 2000-2004 TOMOJI All Rights Reserved