前回の続き

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
大工

前回の続き

#1

投稿記事 by 大工 » 18年前

とりあえず、さっきまで勉強してきたものでちょっとは解決できました。

func( p[/url][/url] )やfunc( p[2][/url] )はコンパイルできませんでした。

VCでは
error C2087: 'd' : 添字がありません。
'int (*)[1]' と 'int [7][7]' で配列の添字が異なります。
error C2087: 'd' : 添字がありません。

とエラーが返ってきました。
添字を必要なところに書かなければならないのは当然のことですが、my_dice(dice)の部分で'int (*)[1]' と 'int [7][7]' で配列の添字が異なります。とこのエラーが返ってきたのが気になります。なぜ、(*)[1]となるのでようか???

あと、エキスパートCプログラミングを読んで学んだことは「~の配列」という仮引数は「~へのポインタ」として扱われる規定している。また、これは再帰的ではなく「配列の配列」、は「ポインタへのポインタ」になるのではなく、「配列へのポインタ」に書き換えられるのでp[/url][2]という仮引数は(*p)[2]となる。

つまり、p[/url][2], p[3][2], (*p)[2]は同じ扱いなり。*p[2]は, **pと同じ扱いしくなる。

このような理解の仕方でよろしいでしょうか???

また、下記のプログラムではコンパイルもでき実行もできました。

しかし、 d[y][10] += 1;という操作はmain関数内でd[7][7];となっているのにどうして警告もないのでしょうか??

これは、関数内ではアドレスしか送られてきてないために元がどういった形式か分からない(上記の本に書いてありました)から起こるのでしょうか???

もしそうだとしたら、int (*d)[7]はd[なんらかの値][7]の形にどうして合わせないといけないのでしょうか?配列のサイズ(?)を送っても関数ないではわからないのに・・・・

すればするほどポインタがややこしくなってきました。。。

ご協力お願いします><。
#include <stdio.h>
#include <stdlib.h>

void my_dice(int (*d)[7]);

int main(void){

  int dice[7][7];

  int n, cnt;

  int x, y;

  srand(time(NULL));       //乱数の初期化.

  //配列の初期化.

  for(x = 0; x < 7; x++) {

      for(y = 0; y < 7; y++) {

         dice[y][x] = 0;
      }
  }

  printf("試行回数:");

  scanf(" %d", &n);

  for(cnt = 0; cnt < n; cnt++) {

     my_dice(dice);

  }

  return 0;
}

void my_dice(int (*d)[7]) {

  int x, y;

  y = rand() % 6 + 1;

  d[y][10] += 1;

  return;

}

box

Re:前回の続き

#2

投稿記事 by box » 18年前

> d[y][10] += 1;という操作はmain関数内でd[7][7];となっているのにどうして警告もないのでしょうか??

C言語は、そういうものです。
定義した範囲外の領域にアクセスしないようにするのは、
通常、プログラムを書く側の責任です。

大工

Re:前回の続き

#3

投稿記事 by 大工 » 18年前

box様>

では引数ではアドレスしかコピーして関数に渡してないのですか??
たとえ、仮引数が(*a)[10]だとしても関数内でa[0][100]にアクセスできてしまうのですか?

box

Re:前回の続き

#4

投稿記事 by box » 18年前

> では引数ではアドレスしかコピーして関数に渡してないのですか??

関数呼び出しの際、引数に配列を指定したとき、
呼び出される関数ではその引数を当該配列の先頭要素へのポインタとするのは、
これまでのやりとりで見てきたとおりです。

> たとえ、仮引数が(*a)[10]だとしても関数内でa[0][100]にアクセスできてしまうのですか?

コンパイル時には、何もエラーは出ません。
実行時、a[0][100]にアクセスしようとしたとき、
プログラムが即座に落ちるかもしれませんし、落ちないかもしれません。

たまたま即座には落ちなかったとしても、別の変数のための領域や、
あるいはユーザプログラムがアクセスしてはいけない領域を壊していますので、
別のタイミングで突然落ちるかもしれません。こうなると、見つけるのが
やっかいなバグです。

大工

Re:前回の続き

#5

投稿記事 by 大工 » 18年前

box様>

なるほど、色々とありがとうございます。

中途半端に知識をつけてしまうと混乱してしまって。。。

とりあえず、自分の中で形になってきました。

閉鎖

“C言語何でも質問掲示板” へ戻る