![]() |
||||||||||||||||||||||||||||||
![]() |
プログラムは、プログラミング言語によって書かれているということはご存知だと思います。Cocoaでは、Objective-C言語というC言語を発展させたプログラミング言語を使用しています。この「Objective-C Primer」では、Objective-C言語を理解する上で必要となるC言語の基礎を学習して、Objective-CとCocoaの入り口までご案内することを目的としています。 ご注意 このサイトに書かれているサンプルコードの実行はあなたの自己責任において行ってください。このサイトおよび私は、このサイトのサンプルコードの実行によって発生するいかなる損害にも責任がなく保証もいたしません。 2006年11月8日修正
ではmain.mを次のようにコーディングしてください。 main.m
main.m ファイルの冒頭部分で 空白行も入れて3行目と4行目でグローバル変数を定義(確保)し、10という整数値で初期化しています。 グローバル変数はこのようにすべての関数の外側で定義され、すべての関数から使う事ができます。グローバル変数は上記のサンプル・コードのようにファイルの冒頭部分で定義します。 一方、ローカル変数は関数の中で定義され、その関数の中でしか使う事ができません。同じ名前のグローバル変数が存在する場合はローカル変数が優先されます。その場合は、その関数内からは、その同名のグローバル変数を使う事はできません。 ローカル変数は、あくまでも定義された関数の中だけが有効な範囲なので、複数の関数内で同名のローカル変数が定義されていてもまったく問題はありません。それぞれの関数内の同名のローカル変数はまったく違うものとして扱われます。このような有効範囲のことをスコープ(scope)と呼びます。 2006 / Nov / 10 更新 赤字で表示されている「ローカル変数」というところを間違って「グローバル変数」と記述していました。すみません。 2006 / Nov / 11 訂正 なお、グローバル変数はプログラムが起動する時にメモリ上に確保されて、プログラムが終了する時にメモリ上から解放されます。一方、ローカル変数は関数が呼び出された時にメモリ上に確保されて、関数が終了する時にメモリ上から解放されます。 2006 / Nov / 11 更新 main 関数 main関数内の2行目でグローバル変数globalIntの値をNSLogを使って表示するようにしています。実行ログ画面には、 globalInt is 10 と表示されます。関数の外で定義された変数が、そのまま関数内でも使えることが分かります。なおコードの中の %2d は「整数値を右寄せ2桁で表示せよ」という意味です main関数の3行目では、main関数の引数として渡された整数値argcを表示しています。実行ログ画面に、 argc is 1 と表示されます。このように引数として渡された値はそのまま関数内でローカル変数として使えます。このサンプルコードの場合は、グローバル変数のargcが隠されて関数内のローカル変数であるargcが有効になっています。 4行目ではargc変数に整数値の55を代入し、5行目で再度argcをログ画面に表示しています。 argc is 55 6行目と7行目ではそれぞれ funcA 関数と funcB 関数を呼び出しています。 2006 / Nov / 7 更新 funcA 関数 funcA 関数では、2行目で globalInt という整数値の変数を定義し、50というリテラル値で初期化しています。これはローカル変数となります。この funcA 関数内では、 main.m ファイルの冒頭で定義されたグローバル変数の globalInt は隠れてしまい、ローカル変数の globalInt が使われます。 2006 / Nov / 8 更新 funcA 関数での空白行を含めての4行目では、 argc という変数の値を表示するようにしています。 このfuncA 関数では argc というローカル変数は定義していませんので、グローバル変数の10という値が表示されます。 argc is 10 5行目では、この argc グローバル変数に複合代入演算子を使って元に値に10を加算しています。複合代入演算子についてはコラムで詳しく説明します。 argc += 10; そして6行目で、加算された argc を表示しています。 argc is 20 2006 / Nov / 9 更新 続けて、7行目ではglobalIntの値をログ画面に表示しています。 globalInt is 50 ローカル変数としてのglobalIntの値が表示されていることがわかります。 8行目では、そのローカル変数のglobalIntに30を加えています。そして9行目で、そのglobalIntの値をログ画面に表示しています。 globalInt is 80 2006 / Nov / 11 更新 funcB 関数 このfuncB 関数では、ローカル変数の定義は一切行っていません。従って2行目ではグローバル変数としてのglobalIntの値をログ画面に表示しています。 globalInt is 10 funcA 関数で、funcA 関数内のローカル変数としてのglobalIntの値を色々と設定しましたが、グローバル変数してのglobalIntには一切影響がおよんでいないことがわかります。 3行目でそのグローバル変数のglobalIntの値に20を加えて、4行目でその値をログ画面に表示しています。 globalInt is 30 main.mのすべてを実行したログ画面は下記(図37)のようになります。 図37 ![]() 2006 / Nov / 11 更新
前項の「グローバル変数とローカル変数」の冒頭で、「ローカル変数は関数が呼び出された時にメモリ上に確保されて、関数が終了する時にメモリ上から解放されます。」と述べました。 このように変数を自動的に解放するために用意されているのが auto 記憶クラス指定子です。auto指定された変数は自動的に解放されるので自動変数と呼ばれます。この auto 記憶クラス指定子は C 言語の予約語のひとつです。自動変数を定義するには下記のように記述します。また自動変数は、あくまでもローカル変数のみに指定できます。 auto int localInt = 100; しかしローカル変数のほとんどは、関数終了時に自動的に解放されるほうが好ましいので、auto 記憶クラス指定子は省略できることになっています。なにの指定子もついていないローカル変数は自動的に自動変数になることになっています。 int localInt = 100; auto 記憶クラス指定子については、C言語予約語一覧 でも説明しています。 2006 / Nov / 12 更新 static 記憶クラス指定子 グローバル変数はプログラムの起動時から終了時までメモリ上に常駐し値の保持を続けます。一方、ローカル変数(自動変数)は関数が終了するとメモリ上から解放されて保持していた値もなくなります。これはメモリの節約の面で有効であり、また、グローバル変数と違い、その関数内だけで使用できるということは安全性の面からも好ましいことです。 しかし、メモリの節約を考えないのであれば、その関数内だけで有効で、しかも関数終了後も値を保持しているローカル変数があれば、安全性という面で有効な便利な変数ができます。 そこでこのような、関数の終了後もメモリ上から解放されずに値を保持するローカル変数を定義することができるのが static 記憶クラス指定子です。static指定された変数は 静的変数 と呼ばれます。 static int staticInt = 100; static 記憶クラス指定子については、C言語予約語一覧 でも説明しています。 では、前回の「最小構成のコマンドラインツールを作ってみる」を参考にして、「static」というプロジェクトを作ってみてください。面倒であれば前項の「volatile」プロジェクトを使ってもらっても結構です。 作成した static プロジェクトの main.m ファイルを下記のようにコーディングします。 main.m
上記のサンプルコードの実行ログ画面は次のようになります(図38)。 図38 ![]() funcA 関数の自動変数 sum は関数が呼び出されるたびに新たに定義され 0 で初期化されています。そして sum 自動変数は関数が終了するたびにメモリから解放されています。 それに対して funcB 関数の静的変数 sum は、関数が最初に呼び出された時に1度だけ定義され 0 で初期化されます。funcB 関数が終了しても静的変数 sum はメモリから解放されることなく値を保持します。2度目以降、funcB 関数が呼びだされても静的変数 sum を新たに定義することはなく、初回に呼び出された時に確保した(定義した)静的変数 sum をそのまま使います。 なお、グローバル変数も静的変数も、そのプログラムが終了する時に消滅します(確保したメモリを解放します)。自動変数は関数が終了した時点で消滅していますので、プログラム終了以前に確保したメモリは解放されています。 2006 / Nov / 13 更新
localInt = 100; 上記のコードの中の「=」は、単純代入演算子またはたんに代入演算子と呼ばれます。これは、一般的な等号(イコール)という意味ではなく、左項の変数の値を右項の変数または直定数または定数の値で置き換えるという意味です。右項には値を返す関数なども使えます。この代入を行うと、左項の変数に保持されていた値はなくなり、右項の値に置き換わってしまいます。 なお、等号を表す演算子は「==」が使われます。 複合代入演算子 複合代入演算子は左項の値に右項の値を足したり・引いたり・かけたり・割ったりして、その結果の値を再び左項に入れ直す演算子です。 localInt += 50; 上記は、 localInt = localInt + 50; という意味になります。もとの localInt の値が100であれば、上記の式の実行後は localInt の値は150になります。 localInt -= 75; 上記は、 localInt = localInt - 75; という意味になり、 localInt の値は75になります。 localInt *= 4; 上記は、 localInt = localInt * 4; という意味になり、 localInt の値は300になります。 localInt /= 3; 上記は、 localInt = localInt / 3; という意味になり、 localInt の値は100になります。 なお、「 * 」は「 かける(×)」を表す演算子です。 2006 / Nov / 17 更新
|
![]() |
||||||||||||||||||||||||||||
![]() |