わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

引数を入れるカッコの後ろに配列の大カッコが来るような関数

C言語の素人である筆者は,「きっと配列の大きさを決めていないのが良くないのだろう」と思い,配列の要素数を決めて再度コンパイルに挑戦してみた.やはり,

char[256] sub( char a[], char b[] )

に対し,宣言が間違えているとコンパイラがエラーを出す.関数には基本型変数(スカラ変数=単一の値しか保持できない変数)しか,値を返さないようである.関数に型はあるが,変数の型を全部許している訳ではなさそうである.
(ここが変だよC言語〈上〉, pp.101-102)

説明はその通りなのですが,関数の宣言のしかたが,Cらしくありません.Javaのようです.Javaでも,こういう戻り値の型を持つメソッドは,見たことがないのですが.
Cっぽく書くなら,

char sub( char a[], char b[] )[]

char sub( char a[], char b[] )[256]

のような.まあこれらでも,ダメなものはダメでno still means no,理由は,上の引用の通りです.
とはいえ,引数の後ろに配列の [ ] が来て,文法的に正しいような書き方も,できます.
C言語によるプログラミング―スーパーリファレンス編』のp.81に,「配列を指すポインタを返す関数」として,int (*a(double))[2] という例があります.これは,引数はdouble型で,戻り値はint (*)[2]型となるような関数型の識別子aを表しています.
コードを書いてみますかね.

#include <stdio.h>
#include <math.h>

#define DIVISION 36  /* 1周を刻む数 */
#define ANGLE_INIT 1  /* 初期角(ラジアン) */

/* http://www2s.biglobe.ne.jp/~nuts/labo/inti/inti09.html より */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

int (*a(double))[2];  /* ここで実現! */

int main(void)
{
  int (*y)[2] = a(ANGLE_INIT);
  int i;

  for (i = 0; i < DIVISION; i++) {
    printf("y[%2d][0] = %5d, ", i, y[i][0]);
    printf("y[%2d][1] = %5d\n", i, y[i][1]);
  }

  return 0;
}

int (*a(double d))[2]
{
  static int x[DIVISION][2];
  int i;

  for (i = 0; i < DIVISION; i++) {
    double ang = d + (double)i / DIVISION * 2 * M_PI;
    x[i][0] = sin(ang) * 1000;
    x[i][1] = cos(ang) * 1000;
  }

  return x;
}

マクロANGLE_INITの角度(単位はラジアン)を起点として,10度(すみませんがここは度数法で)刻みで36個の角度のサインとコサインを1000倍にした値を求めます.