#include #include /*======== 関数プロトタイプ ========*/ /* プログラムの中で別に作成した関数を参照するときは、 関数プロトタイプを作成する。 関数プロトタイプは、include文と同様に、 ソースファイルの最初にまとめて記述する。 */ int aerdt( int ihx, int idx, int ilx, int nx, int *ista, int iyy, int imm, int imiss, float rmiss, int *icheck, float *p, int *iz, float *t, int *iu, int *id, float *s ); float f_tdew( float t, float h ); /*======== 露点温度を計算するための関数 ========*/ /* 関数の種類は浮動小数点(float)型、関数名はf_tdewとする。 引数はt、h(float型)である。 */ float f_tdew( float t, float h ) { /* 変数を宣言する。 */ float tdew; /* 露点温度を計算する。 logは対数関数である。 */ tdew = 35.86 + (t-35.86) / (1. - (t-35.86) / 237.3 * log (h) / 17.27); /* 関数はreturn文で終了する。 変数tdewの値が関数f_tdewの値として返される。 */ return tdew; } /*======== main関数 ========*/ /* プログラムはmain関数から実行される。 */ int main( void ) { /* 配列の大きさ: ihmaxは1日の観測回数(=4)、idmaxは1月の日数(=31)、 ilmaxは気圧面の数(=26)、nmaxは地点数(=1)である。 */ int ihmax=4, idmax=31, ilmax=26, nmax=1; /* 配列(入力データ)の宣言: ista [nmax]: 観測地点番号。東京(大手町)は44132など。 icheck [ihmax, idmax, nmax]: データが存在する場合は1、 存在しない場合は0。 iz [ihmax, idmax, ilmax, nmax]: ジオポテンシャル高度 [m]。 iu [ihmax, idmax, ilmax, nmax]: 相対湿度 [%]。 id [ihmax, idmax, ilmax, nmax]: 風向 [°、北=0、東=90]。 p [ihmax, idmax, ilmax, nmax]: 気圧 [hPa]。 t [ihmax, idmax, ilmax, nmax]: 気温 [℃]。 s [ihmax, idmax, ilmax, nmax]: 風速 [m/s]。 配列のサイズが大きいので、静的変数(static)として宣言する。 staticでは、関数が呼ばれるごとに新たにメモリを確保するのではなく、 プログラムが終了するまで固定されたメモリを用いる。 */ static int ista[1],icheck[4*31*1], iz[4*31*26*1], iu[4*31*26*1], id[4*31*26*1]; static float p[4*31*26*1], t[4*31*26*1], s[4*31*26*1]; /* 配列(出力データ)の宣言: td [ihmax, idmax, ilmax, nmax]: 露点温度 [℃]。 */ static float td[4*31*26*1]; int ihh, idd, imm, iyy, ista1, i, il, ip, status; FILE *fp; /* 欠損値: データが無効のとき、imiss、rmissで指定された値が格納される。 整数型の場合はimiss、浮動小数点型の場合はrmissである。 */ int imiss = 999999; float rmiss = 1.0e9; /* 地点番号を指定する。 入力を求めるメッセージを標準出力に書き出す。 */ printf( "%s\n", "Station No. ?" ); /* scanf文で入力値を読みこむ。 */ scanf( "%d", &ista1 ); ista[0] = ista1; /* 日時を指定する。 入力を求めるメッセージを標準出力に書き出す。 */ printf( "%s\n", "Year, Month, Day, Hour(3,9,15,21) ?" ); /* scanf文で入力値を読みこむ。 */ scanf( "%d,%d,%d,%d", &iyy, &imm, &idd, &ihh ); ihh = (ihh + 3) / 6; /* 関数aerdtによって、指定された年、月の観測データを読むこむ。 ※関数aerdtは、iyy、immで指定された年、月について データを読みこむ。 */ status = aerdt (ihmax, idmax, ilmax, nmax, ista, iyy, imm, imiss, rmiss, icheck, p, iz, t, iu, id, s); /* ここからforループが始まる。 各時刻の各気圧面について、露点温度を計算する。 */ for (i=1; i<=ihmax*idmax*ilmax*nmax; i++) { /* 出力データを格納する配列に、あらかじめ欠損値を入れておく。 */ td[i-1] = rmiss; /* データが存在する場合だけ、 つまり、t[i-1]、iu[i-1]がゼロでない場合だけ、 計算を実行する。*/ if (t[i-1] != rmiss && iu[i-1] != imiss){ td[i-1] = f_tdew( t[i-1]+273.15, 0.01*iu[i-1] ) - 273.15; } /* ここでforループが終了する。 */ } /* 出力ファイルを開く。 モードは"w"(テキストファイルへの書き出し)を指定する。 */ fp = fopen( "output.txt", "w" ); /* ここからforループが始まる。 指定気圧面について、結果を出力する。 地上(il=1)の結果は出力しない。 */ for (il=2; il<=ilmax; il++) { /* データが存在する場合だけ、 つまり、p[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax]、 t[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax]、 td[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax]が欠損値でない場合だけ、 結果を出力する。*/ if (p[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax] != rmiss && t[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax] != rmiss && td[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax] != rmiss) { /* 気圧、気温、露点温度を出力する。 */ ip = p[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax]; fprintf( fp, " %4d %5.1f %5.1f\n", ip, t[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax], td[(ihh-1)+(idd-1)*ihmax+(il-1)*idmax*ihmax] ); } /* ここでforループが終了する。 */ } /* ファイルを閉じる。 */ fclose( fp ); return 0; }