情報証明論 第8章 プログラムの関数化

第2節 関数が関数を呼ぶ

目次


第1節 配列と関数の値

第2節 関数が関数を呼ぶ

第3節 引数への結果代入


テスト

Logをみる

Back
 

第8章 プログラムの関数化 第2節 関数が関数を呼ぶ

 正しさの証明された関数仕立てのプログラムはまた他の関数の中で使うことができます。したがって正しいプログラムは巻き上げてより大きな規模の正しいプログラムを作ってゆくことができるのです。

 また関数の中で関数を使うメリットは、作業領域を小さくできることです。というのは前節の配列の要素を加えるプログラムを見て分かるように、本来作業領域として整数変数s ひとつで済むところを、non-overwritingとするために整数配列s[MAX_N]を使っているのです。もし2次元配列の要素を加えるのはMAX_N×MAX_N の大きな作業領域が必要になります。しかし関数を使うとMAX_Nの大きさで十分です。

例1 前節のsumarray_prgという関数を使ってn行m列の整数行列の要素の和を求める、上書きをしないプログラムを作れ。

解)ワーク領域として1次元配列sを利用し、次のように関数summatrix_prgを作る。

 
int summatrix_prg(int a[MAX_N][MAX_N],int n,int m)
{
 int s[MAX_N],i,j;
 if (!(0< n && n< MAX_N && 0< m && m< MAX_N))return -1;
 for (i=1;i<=n;i++)s[i]=sumarray_prg(a[i],n);
 return sumarray_prg(s,m);
}
これをテストする全体のプログラムは、例えば

#include 
#include 
#include 
#define MAX_N 100	//Maximum size 

int summatrix_prg(int a[MAX_N][MAX_N],int n,int m);
int sumarray_prg(int a[MAX_N],int n);

int main(void)
{ int b[MAX_N][MAX_N],k,m;
 m=3;
 b[1][1]=1;b[1][2]=2;b[1][3]=3;
 b[2][1]=1;b[2][2]=2;b[2][3]=3;
 b[3][1]=2;b[3][2]=3;b[3][3]=4;
 k=summatrix_prg(b,m,m);
 printf("sum of elements=%d \n",k);	
}
int sumarray_prg(int a[MAX_N],int n)
{
 int s[MAX_N],i;
 if (!(0< n && n< MAX_N))return -1;
 else
 {
  s[0]=0;
  for (i=0;i< n;i++)
  { s[i+1]= s [i] + a[i+1];
  } 
 return s[n];
 }
}

int summatrix_prg(int a[MAX_N][MAX_N],int n,int m)
{
 int s[MAX_N],i,j;
 if (!(0< n && n< MAX_N && 0< m && m< MAX_N))return -1;
 else
 {
  for (i=1;i<=n;i++)s[i]=sumarray_prg(a[i],n);
  return sumarray_prg(s,m);
 }
}

 このように上書きをしない正しい関数プログラムを、新しい関数プログラムの中で呼ぶことにより、また新しい上書きをしない正しいプログラムを作ることができるのです。

 この論理モデルは示しませんが、FinSequence of INTという型が1次元配列に対応し、Matrix of INT という型が2次元配列に対応する、という事実、およびMatrix of INT という型はFinSequence of INTを要素とするFinSequenceであるという事実(MATRIX_1参照)から容易に導けます。

 またその論理的正しさも証明できます。