特殊相対性理論・電磁気学・数学

物理の暗黒面や面白い問題など。

C言語、ポインタアドレスの変更の注意

2019-11-12 10:26:05 | プログラム・PC

1. まえがき

 ひさしぶりに、プログラムしてみたら、大ボケしてしまった。

2. 問題

 整数値を格納する配列を受け取り,配列に格納された整数値のなかの最大値を示す配列のポイン
 タをポインタ変数 pmaxに格納する関数、setMax を作成し、この関数を呼び出し、動作するプ
 ログラムを作成する。

3. プログラム

 データが配列、 data[]に格納され、データ数をn、data[]の中の最大値を示すポインタを変数
 pmax に格納する。

 はじめ、呼び出しを「 if (setMax(data, N, pmax) == 0)」、関数を
 「int setMax(int data[], int n, int *pmax)」として、うまくいかなかった。何故かというと
 呼び出しで、変数pmaxに格納されているある変数のポインタ(指定されていないのでゴミ)を
 渡し、関数
の中では、そのポインタが示す場所の値を配列の最大値を示すポインタに変更してい
 た。


 正しくは、変数pmaxの場所を示すポインタ(アドレス)を渡して、その場所の値を書き換えな
 ければならなかった。


/* プログラム */
#include <stdio.h>

#define N 10

/* データ配列 data[]、データ数n、ポインタ変数のアドレス(ポインタ) ppmを受取り */
/* data[]の中の最大値を計算し、そのポインタをppmに返す */
int setMax(int data[], int n, int **ppm)
{
  int i, pos;

  if (n<1) return -1;
  pos=0;
  for (i=1; i<n; i++)
    if (data[i] > data[pos]) pos=i;

  *ppm=&data[pos];
  // printf(" data=%d,%d pos=%d\n", data[pos], **ppm, pos);
  return 0;
}

/* メイン */
int main()
{
  int data[N]={5,4,6,8,2,3,1,9,10,7};
  int *pmax;

  if (setMax(data, N, &pmax) == 0)
    printf("max : %d\n", *pmax);
  else
    printf("data error\n");

  return 0;
}

4. あとがき

 このようなプログラムは普通、書かない。呼び出し側でデータ配列は分かっているから、配
 列の添え字を返せばよく、このような誤りも無い。

 なお、デバックはあるサイトで行った、標準入力に制限があるようだが簡単なプログラムに
 は便利のようだ。

以上