マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第7章 関数の学習

第2話 関数の変数の適用範囲(スコープ)

第2話では変数の適用範囲(スコープ)の話をします。

極めて重要な話です。

下記のコードを関数というプロジェクトにコピペしてください。

#include<iostream>//インクルードファイルiostreamの読み込み

#include<conio.h>//while(!_kbhit());を使うためのお呪い

#include<string> //文字列変数を使えるようにするために組み込む

#include <iomanip> //setprecisionを使えるように組み込む

#include <cmath>//powなどを使うときに必要

#include <ctime>//time()(←現時刻発生する関数)を使うために必要

using namespace std;//coutを使うときに必要なお呪い

int f(int x);//関数です。

int main() {//私は社長だ。

  int y, x;

  x = 5;

  cout << "y = f(" << x << ") = " << y << endl;

  while (!_kbhit());//待機させるための命令

  return 0;//int main() を終わるためのお呪い

}

int f(int x) {

  int y=2 * x + 3;

  return(y);

}


前話の最初のコードから

  y = f(x);

を含む2行を削っただけです。

ところが、F5を押すと、

とエラーしてしまいます。

このエラー一覧はデバッカ(デバックをするソフト=虫取りをするソフト=プログラムの欠陥を直す作業を支援してくれるソフト)

がエラー原因をしめしてくれたものです。

そして、プログラムコードの第23行に問題があることを指摘しています。

なぜ、この現象が起きるのでしょうか。

yには関数int f(int x)の方でちゃんと値を入れて初期化したのに、

初期化されていないと出てしまうのでしょうか。

それは変数の適用範囲は関数内に限定されているからです。

ですから、main()で定義されているyとf(x)内で定義されているyは名前が同じでも別の変数なのです。

つまり、関数内で定義された変数は関数内に使用範囲が限定されているのです。

C++の基になったC言語は高速演算やマルチスレッドプログラミングができるだけでなく、

構造化プログラミングができる言語として評判が高かったのです。

構造化の内容として

① 変数内で定義される変数の適用範囲は関数内に限定されている。

② 部品(関数)同士がプラモデルのように単純な結合である。

というものがあります。

マイクロソフトの創業者であるビル・ゲイツが学生時代に開発して愛したBASICは、

重要な欠陥として構造化プログラミングができない言語として有名だったのです。

一応サブルーチンの考え方はありましたが、

変数はすべてグローバル変数だったのです。

グローバル変数は全プログラム内で使える変数です。

逆に関数内でしか使えない変数をローカル変数と呼ぶのです。

C言語やC++では基本はローカル変数を使います。

グローバル変数は、使用が終わってからもメモリ上に居座り続けて、

メモリを無駄にしてしまいます。

C言語やC++の関数も変数も使用が終わるとメモリ上から消える言語なのです。

メモリ節約の思想が徹底していました。

メモリとは関数や変数の活躍する舞台です。

必要な人だけが舞台に出て踊り、

終わったら舞台から去ることが舞台を有効に使う術です。

でないと、舞台が役者でいっぱいになってしまって動きが取れなくなります。

関数も変数も使用している間だけ舞台であるメモリ上に存在して、

自分の出演が終わったらメモリ上から消滅するのです。

このようにしてメモリをうまく使っていることがC言語の最大の特徴だったのです。

メモリ上に生まれたり、消滅を繰り返す関数や変数を動的変数や動的変数と呼びます。

C言語やC++でもグローバル変数を定義することはできます。

ですが、グローバル変数は使っていてもいなくてもメモリ上に存在してメモリを無駄遣いします。

現代のコンピュータはメモリを何十ギガ単位で持っているが普通ですが、

今から36年前のぐらい前のコンピュータは1メガ程度しかメモリを積んでいなかったのです。

ですから、昔はメモリを節約することが今以上に必要だったのです。

そして、現在何十ギガ単位のメモリを持っているコンピュータは、

メモリの節約の必要がないかというと、

そんなことはなくてやはりメモリの節約は必要なのです。

理由は、メモリが大きくなった分、メモリ使用量が大きくなっているのが現状だからです。

メモリ使用という点でプログラムは巨大化しているのです。

というか巨大化することによって昔はできなかった様々なプログラムを組むことができるようになったわけです。

皆さんに第2編で体験していただく数独自動生成ソフトは、基本36スレッド以上で超巨大なプログラミングです。

#include<iostream>//インクルードファイルiostreamの読み込み

#include<conio.h>//while(!_kbhit());を使うためのお呪い

#include<string> //文字列変数を使えるようにするために組み込む

#include <iomanip> //setprecisionを使えるように組み込む

#include <cmath>//powなどを使うときに必要

#include <ctime>//time()(←現時刻発生する関数)を使うために必要

using namespace std;//coutを使うときに必要なお呪い

int f(int x);//関数です。

int main() {//私は社長だ。

  int y, x;

  x = 5;

  y = f(x);

  cout << "y = f(" << x << ") = " << y << endl;

  while (!_kbhit());//待機させるための命令

  return 0;//int main() を終わるためのお呪い

}

int f(int x) {

  int y=2 * x + 3;

  return(y);

}
コピペしてコードは戻しておきましょう。





第7章第1話へ 第7章第3話へ

本講義トップへ