1 / 22

第 12 章 関数と配列

第 12 章 関数と配列. 1 次元配列 2 次元配列 配列を使って結果を返す 演習問題 レポート課題. 9.4 配列変数とポインタ ( 再掲 ). C では、 配列 変数は ポインタ 変数 を用いてアクセスすることが多い. 1000 1004 1008 ・ ・ ・. a[0]. &a[0] は 1000 、 &a[1] は 1004. a[1]. a[2]. a[3]. int *a_p; a_p = &a[0] ;. a[4]. 1000. a_p. a_p は、整数型変数のアドレスが入る

kane-burton
Download Presentation

第 12 章 関数と配列

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第12章 関数と配列 1次元配列 2次元配列 配列を使って結果を返す 演習問題 レポート課題

  2. 9.4配列変数とポインタ (再掲) C では、配列変数はポインタ変数 を用いてアクセスすることが多い 1000 1004 1008 ・ ・ ・ a[0] &a[0]は1000、 &a[1]は1004 a[1] a[2] a[3] int *a_p; a_p = &a[0]; a[4] 1000 a_p a_pは、整数型変数のアドレスが入る ポインタ型変数で(1行目)、配列 a の 先頭の要素の番地を代入する(2行目)

  3. ポインタと配列変数との間の関係 a_p =&a[0]; は、 a_p =a; と書いても良い 1000 1004 1008 ・ ・ ・ a[0] a[1] a[2] 上記の文で、 a_pには、配列aの先頭の要素 a[0]の番地を代入するよ、 という意味。 図示すると、 a[3] a[4] 1000 a_p a_p a[0] 1000

  4. 10.9 関数と配列 プログラム例 10.9.1 mainで関数 sumを 呼び出す時、 a の先頭アドレスを 引数としている … value = sum(count, &a[0]); … float sum(int n, float *x_p) { int i; float s; s = 0.; for (i = 0; i < n; i++) { s += *x_p; x_p++; } return s; } 関数 sumの引数は、 配列の要素数 nとポインタ a[0], a[1]の値が加算される。 ポインタは、&a[0], &a[1], … となる

  5. 10.9 関数と配列 プログラム例 10.9.1 float sum(int n, float *x_p) { int i; float s; s = 0.; for (i = 0; i < n; i++) { s += *x_p; x_p++; } return s; }

  6. 10.9 関数と配列 プログラム例 10.9.1 の mainの4行目 value = sum(count, &a[0]); 上記の文は、下のように書いても同様 (この方が一般的) value = sum(count, a);

  7. 12.11次元配列 #include <stdio.h> double sum(int n, double x[]); int main(void) { double a[5] = {1.56, 3.24, 5.24, 3.24, 6.23}; int count = 5; double value; value = sum(count, a); printf("総和 = %f\n", value); return 0; } double sum(int n, double x[]) { int i; double s; s = 0.; for (i = 0; i < n; i++) s += x[i]; return s; } プログラム例10.9.1 改 *x_pのかわりに x[] *x_pのかわりに x[] *x_p; x_p++のかわりに x[i]

  8. 12.11次元配列 プログラム例12.1.1 #include <stdio.h> void disp_1D_array(int n, double x[]); int main(void) { double a[] = {3.24, 1.76, 5.32, 2.37, 4.33, 1.26}; int asize = 6; disp_1D_array(asize, a); return 0; } void disp_1D_array(int n, double x[]) { int i; for (i = 0; i < n; i++) printf("%f\n", x[i]); } 初期値があればサイズは省略可

  9. 10.10 関数と2次元配列 プログラム例 10.10.1 #include <stdio.h> void disp_2D_array(int nrow, int ncol, double *a_p); int main(void) { int nrow = 3, ncol = 3; double a[3][3] = {{1.56, 3.24, 5.24}, {3.24, 6.23, 8.16}, {7.32, 2.86, 4.12}}; disp_2D_array(nrow, ncol, &a[0]); return 0; } void disp_2D_array(int nrow, int ncol, double *a_p) { int i, j; for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { printf(" %7.2f", *a_p); a_p++; } printf("\n"); } } 内側の波カッコは人が読みやすくするため

  10. 12.22次元配列 行の大きさは省略できるが、列の大きさは省略できない x[3][3]→x[][3] 記憶領域→1次元的 a[m][n]の行列表現 1行目 2行目 m行目 1行目 折り返し場所の情報は省略できない

  11. 12.22次元配列 プログラム例 12.2.1 #include <stdio.h> void disp_2D_array(int n, double x[][3]); int main(void) { int nrow = 3; double a[3][3] = {{3.24, 1.76, 5.32}, {2.37, 4.33, 1.26}, {1.86, 1.86, 3.64}}; disp_2D_array(nrow, a); return 0; } void disp_2D_array(int n, double x[][3]) { int i, j; for (i = 0; i < n; i++) { for (j = 0; j < 3; j++) { printf(" %7.2f", x[i][j]); } printf("\n"); } } 3という数字があちこちに散逸

  12. 12.22次元配列 プログラム例 12.2.2 #include <stdio.h> #define NROW 3 #define NCOL 3 void disp_2D_array(double x[][NCOL]); int main(void) { double a[NROW][NCOL] = {{3.24, 1.76, 5.32}, {2.37, 4.33, 1.26}, {1.86, 1.86, 3.64}}; disp_2D_array(a); return 0; } void disp_2D_array(double x[][NCOL]) { int i, j; for (i = 0; i < NROW; i++) { for (j = 0; j < NCOL; j++) { printf(" %7.2f", x[i][j]); } printf("\n"); } } 行数、列数を集中管理

  13. 呼び出し側の配列へデータを返す プログラム例 10.10.2 c11 c12 c13 c21 c22 c23 c31 c32 c33 a11 a12 a13 a21 a22 a23 a31 a32 a33 b11 b12 b13 b21 b22 b23 b31 b32 b33 = + a11+b11 a12+b12 a13+b13 a21+b21 a22+b22 a23+b23 a31+b31 a32+b32 a33+b33 = 関数sum: 配列aとbから、上記のように新しい配列cを計算。 配列c(新しいデータ)をmainに返すには?

  14. 呼び出し側の配列へデータを返す プログラム例 10.10.2 … sum(nr, nc, &a[0][0], &b[0][0], &c[0][0]); … void sum(int nrow, int ncol, float *a_p, float *b_p, float *c_p) { int i, j; for (i = 0; i < nrow; i++) for (j = 0; j < ncol; j++) { *c_p = *a_p + *b_p; a_p++; b_p++; c_p++; } } sumの呼び出し前: 配列 c[i][j]は 未定 sumの呼び出し後: 配列 c[i][j]には a[i][j]+b[i][j]が入る

  15. #include <stdio.h> #define NROW 3 #define NCOL 3 void sum(int x[][NCOL], int y[][NCOL], int z[][NCOL]); void disp_2D_array(int u[][NCOL]); int main(void) { int a[NROW][NCOL] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int b[NROW][NCOL] = {{11, 12, 13}, {14, 15, 16}, {17, 18, 19}}; int c[NROW][NCOL]; disp_2D_array(a);disp_2D_array(b); sum(a, b, c); disp_2D_array(c); return 0; } 12.3 配列を使って結果を返す プログラム例 12.3.1

  16. 12.3 配列を使って結果を返す void sum(int x[][NCOL], int y[][NCOL], int z[][NCOL]) { int i, j; for (i = 0; i < NROW; i++) { for (j = 0; j < NCOL; j++) { z[i][j] = x[i][j] + y[i][j]; } } } void disp_2D_array(int u[][NCOL]) { int i, j; for (i = 0; i < NROW; i++) { for (j = 0; j < NCOL; j++) { printf(" %10d", u[i][j]); } printf("\n"); } }

  17. 演習問題12.2 #include <stdio.h> #define NROW 3 #define NCOL 3 void sum_ave(double ?????????, double *s, double *av); int main(void) { double s, av; double a[NROW][NCOL] = {{3.24, 1.76, 5.32}, {2.37, 4.33, 1.26}, {1.86, 1.86, 3.64}}; sum_ave(??????????); printf("総和 = %7.2f, 平均 = %7.2f¥n", s, av); return 0; } void sum_ave(double?????????, double *s, double *av) { int i, j; *s = 0; for (i = 0; i < ????; i++) { for (j = 0; j < ????; j++) { *s += ???????; } } *av = ??????????????; } 配列要素の数値の総和と 平均値を計算する関数 総和の計算 平均値の計算

  18. 演習問題12.3 #include <stdio.h> #define NROW 3 #define NCOL 3 void sum(int x[][NCOL], int y[][NCOL], int z[][NCOL]); void diff(int x[][NCOL], int y[][NCOL], int z[][NCOL]); void prod(int x[][NCOL], int y[][NCOL], int z[][NCOL]); void disp_2D_array(int x[][NCOL]); int main(void) { int a[NROW][NCOL] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int b[NROW][NCOL] = {{11, 12, 13}, {14, 15, 16}, {17, 18, 19}}; int c[NROW][NCOL]; disp_2D_array(a);disp_2D_array(b); sum(???????); disp_2D_array(c); diff(???????); disp_2D_array(c); prod(???????); disp_2D_array(c); return 0; }

  19. 演習問題12.3(つづき) void sum(int x[][NCOL], int y[][NCOL], int z[][NCOL]) { } void diff(int x[][NCOL], int y[][NCOL], int z[][NCOL]) { } void prod(int x[][NCOL], int y[][NCOL], int z[][NCOL]) { int i, j, k; for (i = 0; i < ????; i++) { for (j = 0; j < ????; j++) { z[i][j] = 0; for (k = 0; k < ????; k++) z[i][j] += ???????????????; } } } void disp_2D_array(int x[][NCOL]) { } 行列の和 行列の差 行列の積

  20. 演習問題12.4 #include <stdio.h> #define NROW 3 #define NCOL 4 void sweep_out(double ?????????); void disp_2D_array(double ?????????); int main(void) { double a[NROW][NCOL] = {{2, 3, 1, -1}, {3, 1, 2, 7}, {1, 2, 3, 6}}; disp_2D_array(?); sweep_out(?); disp_2D_array(?); return 0; } 掃出法

  21. 演習問題12.4(つづき) void sweep_out(double ?????????) { int i, j, k; double w; for (k = 0; k < NROW; k++) { w = a[k][k]; for (j = 0; j < NCOL; j++) a[k][j] /= w; for (i = 0; i < NROW; i++) { if (i != k) { w = a[i][k]; for (j = 0; j < NCOL; j++) a[i][j] -= w * a[k][j]; } } } } void disp_2D_array(double ?????????) { ????????? } k行目の成分をその対角成分で割る 掃き出し操作

  22. 第1回レポート(必須) 課題 • 課題:教科書p.114の演習問題12.3または 12.4 • 提出期限:2007年10月26日(金) 17:00 • 提出場所:ネットワーク実験室(1)の入口近くの箱 • 今回のレポートでは以下の項目をいれること。 • 表紙は不要。 • 学籍番号、氏名 • 問題番号 • ソースリスト • 実行結果 • 感 想(5行以上) レポートのファイルは 保存しておくこと

More Related