Cのポインタの使い方で勘違いしてたこと

ビギナー向けの教科書のポインタの説明に書いてあるようなことをぼんやりと想像しながら書いたら失敗したのでメモ:


  1. [2010.1.2]

      int daytab[2][13];

    と宣言したとき daytab + i は daytab = &daytab[0][0] から数えて i × sizeof( int * 13 ) バイト先のアドレスを渡す。だから親の関数から、配列 int a[3][4] を子の関数に渡すときの引数は

    f(int daytab[2][13]) { ... }
    f(int daytab[][13]) { ... }
    f(int (*daytab)[13]) { ... }

    のいずれかの形で書いて、スキップサイズの 13 を子の関数に教えないといけない。

  2. [2009.12.11]

    void inputInt (int *a) {
      *a= 999;
    }

    というソースでは呼び出し

    inputInt(&a);
    のあとで a に整数 999 が入るので、

    void inputFilename (FILE *fp) {
      char * file="test.txt"; // 後でファイル名入力に書き換え
      fp= fopen(file,"r");
    }

    というソースでは呼び出し

    inputFilename(fp);
    のあとで fp にファイル test.txt へのファイルポインタが入っていると思っていた。勘違いも甚だしい。ポインタ変数そのものは「値渡し」だから、呼び出し側のポインタ変数の内容を書き換えない。次のコードは動作する。

    FILE * inputFilename (void) {
      FILE *fp;
      char * file="test.txt"; // 後でファイル名入力に書き換え
      fp= fopen(file,"r");
      return fp;
    }

    というソースを書いて、呼び出しは

    fp= inputFilename();
    とする。