8−2 ポインタ変数を引数とする関数

前の8−1のプログラムでは、求めるべき乗の結果の値がlong int型で表現できる範囲に限られていた。ここでは、もっと大きな値が求められるような工夫をする。

例題

整数のべき乗Xのn乗を関数をもちいてもとめる。Xとnとは標準入力から入力し、結果を標準出力に出力する。結果はint型配列に、1けたを1要素に求める。結果の値は、30けた以下とし、値のチェックは省略する。

べき乗は以下の手順で求める。

@配列の初期化

  値の初期値を1とする。配列要素の内容が99であるとき、データ(けた)の終わりをしめすものとする。

Aけた上げの初期化

  下のけたからのけた上がりを格納する変数Cを0とする。

B1けたずつ積を求める。

  Kekka[j](j=0)とxとの積に下からのけた上がりを加え、結果の一の位を新しいkekka[j]とする。10の位は次のけた(kekka[j+1])へのけた上げとして、Cに格納する。

CBの処理を全けたについて(j=0,1、・・・kekka[j+1]=99であるj)おこなう。

D最後のけた(kekka[j]が99であるj)では、乗算はせず、下のけたからのけた上げが0でないときのみ、kekka[j]にけた上げを入れ、kekka[j+1]を99とする。

EA〜Dを繰り返す。

[問題の分析]

(1)べき乗を算出する関数pow()

  入力(引数):x、n、結果を格納するint型配列へのポイント

  出力(返却値):結果の値の桁数を返す。

(2)データの入出力

  標準入力からのx、nの入力、標準出力への結果の出力はmain()でおこなう。

[プログラムの作成]

/*-----------------------------------------------

       べき乗を求める

-------------------------------------------------*/

#include<stdio.h>

  /*関数の宣言*/

int   pow(int x,int n,int *pk);   /*べき乗を算出する*/

main()

{

   int      x,n;      /*入力データ*/

   int       y[31];     /*結果*/

   int      keta;      /*結果のけた*/

   int       i;     /*添字*/

   /*データの入力*/

  printf("input x n:");

  scanf("%d %d",&x,&n);

  /*べき乗の算出*/

  keta=pow(x,n,y);

  /*結果の表示*/

printf("x=%d n=%d\n",x,n);

printf("x**n=%ld\n");

for(i=keta-1;i>=0;i--)printf("%ld",y[i]);

printf("\n");

}

/*-----------------------------------------------

       べき乗の算出

-------------------------------------------------*/

int    pow(int a,int b,int *pk)

{

   int      i,j;      /*添字*/

   int       c;      /*けた上げ*/

   int      tmp;      /*1けたの積の結果*/

  /*初期化*/

  *pk=1;

  *(pk+1)=99;

  /*aをb回掛ける*/

   for(i=0;i<b;i++){

      for(j=0,c=0;*(pk+j)!=99;j++){  /*1けたずつ積をもとめる*/

           tmp=*(pk+j) * a+c;

           *(pk+j)=tmp % 10;  /*1の位*/

           c=tmp/10;       /*けた上げ*/

       }

      if(c!=0){         /*1けたずつ積を求める*/

         *(pk+j)=c;

         j++;         /*1けた増える*/

         *(pk+j)=99;

      }

   }

   return(j);

 }

  

[実行結果]

 input x n:10 5

 x=10 n=5

 x**n=100000

解説

【call by reference】 配列などの多くのデータを関数に渡したいときや、呼び出し側のメモリ領域を関数内で直接変更したい時には、引数としてそのオブジェクトのアドレスを渡す方法。

 

 

次へ