第12講 ベクタの学習
第11話 静的変数(static変数)
まず、下のコードをタイピングするか、
参考ダウンロードファイルをコピペして
#include<vector> //ベクタを使うのに必要なvectorをインクルード
#include <stdio.h> //printfを使うのに必要なstduio.hをインクルード
using namespace std; //ベクタを使うために必要
int *f();
void main(){
   int *b;
   b=f();
   printf("main上での表示 ");
   for(char i=0;i<3;i++)printf("a[%d]=%d ",i,b[i]); //main上でデータを表示
}

int *f(){
   int a[3];
   for(char i=0;i<3;i++)a[i]=i+5; //関数f()においてデータを作成
   return(a);
}

プログラムを実行して見て下さい。
実行画面は
main上での表示 a[0]=5 a[1]=6 a[2]=7
になるはずですが、
実際には
main上での表示 a[0]=1955112672 a[1]=1955524233 a[2]=8467342
と奇妙な結果になります。

第7講第10話において、
関数も変数と同様にメモリー上で働きます。
変数や関数などの役者が、
踊ったり演じたりする舞台がメモリーです。
実は、関数は呼び出されるまでメモリー上に存在しません。
呼び出され任務を遂行している間だけ舞台に立つのです。
呼び出されるとは、mainなどに仕事を命じられることです。
関数は、呼び出される前はどこにも存在していません。
ですから、呼び出されなければ、
関数上で変数・配列・ポインタが宣言されていても、
それらの変数などのためのメモリーは存在しません。
呼び出され、
宣言されている行に達したときにはじめてメモリーの確保が行われ、
任務が遂行し終わると関数自体が消えてしまいますので、
関数の中で使われていた変数も消滅するのです。
関数の中で使われている変数に当てられていたメモリー領域が、
自動的に解放されるのです。
このように生成消滅を繰り返す関数と変数を
それぞれ動的関数、動的変数といいます。
mallocを使ってメモリーを確保しない変数は、
すべて動的変数です。』
と記述してあったこと、記憶にあるでしょうか。
これを読んで、先の奇妙な結果の原因を推測できたとすれば、
あなたはかなり慧眼な方です。
   int a[3];
によって関数上で宣言された場合と、
同じく関数上で、
   int *a=(int *)malloc(sizeof(int)*3);
定義された場合では、
決定的な違いがあります。
試しに、int a[3];をint *a=(int *)malloc(sizeof(int)*3);
に変更して再度実行してみて下さい。
実行画面は
main上での表示 a[0]=5 a[1]=6 a[2]=7
とプログラマが意図した通りになりました。
プログラマがmallocで確保したメモリーは、
関数が消滅しても、残り続けます。
それに対して、普通の変数や配列は、
関数の消滅と共に消滅します。
普通の変数と関数は生成消滅を繰り返します。
生成消滅を繰り返す変数を動的変数、
生成消滅を繰り返す関数を動的関数といいます。
普通の関数や変数という曖昧な言い方をしましたが、
既習の内容では、malloc使ってメモリーを確保しない、
関数や変数はすべて動的関数および動的変数です。
それに対して、
プログラムが作動中メモリーに常駐する関数や変数があります。
メモリーに常駐する関数を静的関数=static関数、
メモリーに常駐する変数を静的変数=static変数といいます。
静的変数を用意するには、
   static int b;
とまえにstaticを付けるだけです。
静的配列も同様で、
   static int a[3];
とすれば良いのです。
#include<vector> //ベクタを使うのに必要なvectorをインクルード
#include <stdio.h> //printfを使うのに必要なstduio.hをインクルード
using namespace std; //ベクタを使うために必要
int *f();
void main(){
   int *b;
   b=f();
   printf("main上での表示 ");
   for(char i=0;i<3;i++)printf("a[%d]=%d ",i,b[i]); //main上でデータを表示
}

int *f(){
  
static int a[3];
   for(char i=0;i<3;i++)a[i]=i+5; //関数f()においてデータを作成
   return(a);
}
と変更して実行し直すと、
main上での表示 a[0]=5 a[1]=6 a[2]=7
プログラマが考えている通りの実行結果になります。
改良前のint a[3];では動的配列で、
関数が任務を終えると、
関数の消滅と共に配列も消滅の運命を辿ったのに対して、
静的配列の場合、プログラムが実行されている間は、
メモリーに常駐しているからです。


さて、今話の話をヒントにして、
関数側でベクタを定義して、
データを作成して、
そのデータをmainや他の関数で利用する方法について
考えてください。


第10話へ 第12話へ



a

eclipse c++ 入門講義第1部へ

魔方陣 数独で学ぶ V
BA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ