過去に渡した値を返す関数
関数int delay6(int
var)は1つのint型の引数varを持ち,関数の返す値は,6回前にこの関数が呼ばれた時のvarである。
ただし,最初の6回の呼び出し時の返す値は0とする。
方法1 現在値,前回値を保存しておく静的変数を使う方法
#include <stdio.h>
#include <stdlib.h>int delay6(int var)
{
static int previous0=0; /*受け取った値*/
static int previous1=0; /*前回受け取った値*/
static int previous2=0; /*その前回受け取った値*/
static int previous3=0; /*その前回受け取った値*/
static int previous4=0; /*その前回受け取った値*/
static int previous5=0; /*その前回受け取った値*/
static int previous6=0; /*その前回受け取った値=返す値*/
previous6=previous5;
previous5=previous4;
previous4=previous3;
previous3=previous2;
previous2=previous1;
previous1=previous0;
previous0=var;
return previous6;
}int main()
{
int i;
int x,y;
for(i=0;i<15;i++) {
x=rand();
y=delay6(x);
printf("%2d x=%6d y=%6d\n",i,x,y);
}
return 0;
}/* 実行結果
0 x= 41 y= 0
1 x= 18467 y= 0
2 x= 6334 y= 0
3 x= 26500 y= 0
4 x= 19169 y= 0
5 x= 15724 y= 0
6 x= 11478 y= 41
7 x= 29358 y= 18467
8 x= 26962 y= 6334
9 x= 24464 y= 26500
10 x= 5705 y= 19169
11 x= 28145 y= 15724
12 x= 23281 y= 11478
13 x= 16827 y= 29358
14 x= 9961 y= 26962
*/この方法だと,10個前の値を返す関数を作るには変数を10個作らなければならないし,
100個前の値を返す関数を作るには変数を100個作らなければならない。
方法2 現在値,前回値を保存しておく静的配列変数を使う方法
#include <stdio.h>
#include <stdlib.h>int delay6(int var)
{
static int buffer[8]={0,0,0,0,0,0,0,0};
buffer[6]=buffer[5];
buffer[5]=buffer[4];
buffer[4]=buffer[3];
buffer[3]=buffer[2];
buffer[2]=buffer[1];
buffer[1]=buffer[0];
buffer[0]=var;
return buffer[6];
}int main()
{
int i;
int x,y;
for(i=0;i<15;i++) {
x=rand();
y=delay6(x);
printf("%2d x=%6d y=%6d\n",i,x,y);
}
return 0;
}/* 実行結果
0 x= 41 y= 0
1 x= 18467 y= 0
2 x= 6334 y= 0
3 x= 26500 y= 0
4 x= 19169 y= 0
5 x= 15724 y= 0
6 x= 11478 y= 41
7 x= 29358 y= 18467
8 x= 26962 y= 6334
9 x= 24464 y= 26500
10 x= 5705 y= 19169
11 x= 28145 y= 15724
12 x= 23281 y= 11478
13 x= 16827 y= 29358
14 x= 9961 y= 26962
*/この方法だと,10個前の値を返す関数を作るには変数の移動を10回行わなければならないし,
100個前の値を返す関数を作るには変数の移動を100回行わなければならない。
方法3 静的配列変数をリングバッファとして使う方法
静的配列のお尻と先頭をつないでリング状のデータ保存領域のように考え,新しいデータを保存する場所を
示す変数putposと,取り出すデータを示す変数getposを用いて,データを順送りにせず,2つの変数を変化させる。この方法はリングバッファと呼
ばれ,用途が広い。
プログラム中,7号室の次に0号室がつながっているリング状の配列があり,この8要素の中で,putposとgetposが追いかけっこをするように移動しているのがわかる。
#include <stdio.h>
#include <stdlib.h>
int delay6(int var)
{
static int buffer[8]={0,0,0,0,0,0,0,0};
static int putpos=7;
static int getpos=0;
buffer[putpos]=var;
putpos++;
if (putpos==8) putpos=0;
getpos++;
if (getpos==8) getpos=0;
return buffer[getpos];
}
int main()
{
int i;
int x,y;
for(i=0;i<15;i++) {
x=rand();
y=delay6(x);
printf("%2d x=%6d y=%6d\n",i,x,y);
}
return 0;
}
/* 実行結果
0 x= 41 y= 0
1 x= 18467 y= 0
2 x= 6334 y= 0
3 x= 26500 y= 0
4 x= 19169 y= 0
5 x= 15724 y= 0
6 x= 11478 y= 41
7 x= 29358 y= 18467
8 x= 26962 y= 6334
9 x= 24464 y= 26500
10 x= 5705 y= 19169
11 x= 28145 y= 15724
12 x= 23281 y= 11478
13 x= 16827 y= 29358
14 x= 9961 y= 26962
*/
テクニック staticの配列変数の初期化について
staticの配列変数の初期化で全てに0を埋める場合,配列の大きさが10個程度なら,これまでの方
法で良いが,100個とか1000個あると,直接0を並べるのは大変である。static変数であることの特性を考えて,initializedのような
int型変数を導入すると,プログラムの動作として初期化出来る。
#include <stdio.h>
#include <stdlib.h>int delay6(int var)
{
static int buffer[8];
static int initialized=0;
static int putpos=7;
static int getpos=0;
int i;
if (initialized==0) {
for (i=0; i<8; i++) buffer[i]=0;
initialized=1;
}
buffer[putpos]=var;
putpos++;
if (putpos==8) putpos=0;
getpos++;
if (getpos==8) getpos=0;
return buffer[getpos];
}int main()
{
int i;
int x,y;
for(i=0;i<15;i++) {
x=rand();
y=delay6(x);
printf("%2d x=%6d y=%6d\n",i,x,y);
}
return 0;
}/* 実行結果
0 x= 41 y= 0
1 x= 18467 y= 0
2 x= 6334 y= 0
3 x= 26500 y= 0
4 x= 19169 y= 0
5 x= 15724 y= 0
6 x= 11478 y= 41
7 x= 29358 y= 18467
8 x= 26962 y= 6334
9 x= 24464 y= 26500
10 x= 5705 y= 19169
11 x= 28145 y= 15724
12 x= 23281 y= 11478
13 x= 16827 y= 29358
14 x= 9961 y= 26962
*/