関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題

Slides:



Advertisements
Similar presentations
第 11 章 関数について 11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 数学関数の自作.
Advertisements

オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
配列の宣言 配列要素の初期値 配列の上限 メモリ領域 多次元配列 配列の応用
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第4回 配列 for文 変数宣言 初期化
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
第13回構造体.
データ構造とアルゴリズム 第10回 mallocとfree
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
問題 1 フィボナッチ数列 xn は次で定義される。
IT入門B2 ー 連立一次方程式 ー.
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
構造体.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
関数 関数とスタック.
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
プログラミング2 関数
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
関数の定義.
プログラミング入門2 第8回 ポインタ 情報工学科 篠埜 功.
アルゴリズムとデータ構造 補足資料5-2 「サンプルプログラムsetop.c」
知能情報工学演習I 第12回(後半第6回) 課題の回答
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
第11回 プログラミングⅡ 第11回
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
関数の再帰呼び出しとは ハノイの塔 リダイレクト レポート課題
関数への道.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
Cプログラミング演習資料.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
プログラミング 3 2 次元配列.
IF文 START もしも宝くじが当たったら 就職活動する 就職活動しない YES END NO.
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
情報基礎演習B 後半第2回 担当 岩村 TA 谷本君.
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
第5回 プログラミングⅡ 第5回
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
精密工学科プログラミング基礎 第7回資料 (11/27実施)
プログラミング入門2 第5回 配列 for文 変数宣言 初期化
ループだよ!難しいよ! 第5章 while(ループ);.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
Cプログラミング演習資料.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第5回 配列 変数宣言、初期化について
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
岩村雅一 知能情報工学演習I 第13回(後半第7回) 岩村雅一
プログラミング演習I 補講用課題
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
= 55 課題6-1 #define _CRT_SECURE_NO_WARNINGS
Presentation transcript:

関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題 第12章 関数と配列 関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題

10.9 関数と配列 プログラム例 10.9.1 #include <stdio.h> 10.9 関数と配列 プログラム例 10.9.1 #include <stdio.h> double sum(int n, double *x_p); 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[0]); printf("&a[0]=%u, 総和 = %f\n", &a[0],value); return 0; } double sum(int n, double *x_p) … 参照呼び出し 関数sum を呼び出す時、配列a の 先頭アドレス(ポインタ定数)を渡す 関数sum の仮引数では、 配列はポインタでうけとる

関数と配列とポインタ C では、配列変数はポインタ変数 を用いてアクセスすることが多い 1.56 a[0] 1000 1008 1016 1024 1032 1040 a[0] 3.24 &a[0] は1000、&a[1] は1008、… a[1] 5.24 a[2] 3.24 … sum(count,&a[0]); //mainの中 double sum(int n, double *x_p) { } a[3] 6.23 a[4] 1000 x_p 関数の実引数にポインタ定数&a[0]を入れて呼ぶと、 その値が関数の仮引数x_pにコピーされる

10.9 関数と配列 プログラム例 10.9.1 main で関数sum を呼び出す時、 配列a の先頭アドレス(ポインタ … 定数)を渡す 10.9 関数と配列 プログラム例 10.9.1 main で関数sum を呼び出す時、 配列a の先頭アドレス(ポインタ 定数)を渡す … value = sum(count, &a[0]); double sum(int n, double *x_p) { int i; double s; printf("&x_p:%u,x_p:%u\n", &x_p,x_p); s = 0.; for (i = 0; i < n; i++) { s += *x_p; x_p++; } return s; 関数 sum の仮引数では、 配列はポインタで受け取る ポインタを介してa[0], a[1],… の 値を代入し、加算する。ポインタ自体は、 &a[0], &a[1],… と変化する

10.9 関数と配列 プログラム例 10.9.1 1000 a[0] 1008 a[1] 1016 a[2] 1024 a[3] 1032 a[4] 1040 . 1.56 3.24 5.24 6.23 double sum(int n, double *x_p) { int i; double s; s = 0.; for (i = 0; i < n; i++) { s += *x_p; x_p++; } return s; x_p i s 1040 5 19.51 1008 1000 1016 1024 1032 2 4 3 1 10.04 13.28 4.80 1.56 0.0

10.9 関数と配列 上記の文は、下のように書いても同様(この方が一般的) プログラム例 10.9.1 の main の4行目 10.9 関数と配列 プログラム例 10.9.1 の main の4行目 value = sum(count, &a[0]); 上記の文は、下のように書いても同様(この方が一般的) value = sum(count, a); 配列の場合、配列名 a がポインタ(正確にはポインタ定数)なので、 & をつけなくても「参照呼び出し」となる。 ポインタ定数 a と ポインタ変数 pの違い: p = a; は可能だが a = p; は不可

12.1 1次元配列 プログラム例 10.9.1 改 #include <stdio.h> 12.1 1次元配列 第12章の流儀 プログラム例 10.9.1 改 #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("a:%u, 総和 = %f\n", a, value); return 0; } double sum(int n, double x[]) int i; double s; printf("&x:%u, x:%u\n", &x, x); s = 0.; for (i = 0; i < n; i++) s += x[i]; return s; *x_p のかわりに x[] *x_p のかわりに x[] *x_p; x_p++ のかわりに x[i]

12.1 1次元配列 プログラム例 12.1.1 #include <stdio.h> 12.1 1次元配列 プログラム例 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]); 初期値があればサイズは省略可

10.10 関数と2次元配列 プログラム例 10.10.1 #include <stdio.h> 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"); 内側の波カッコは人が読みやすくするため

12.2 2次元配列 行の大きさは省略できるが、列の大きさは省略できない a[3][3] → a[][3] 記憶領域→1次元的 12.2 2次元配列 行の大きさは省略できるが、列の大きさは省略できない a[3][3] → a[][3] 記憶領域→1次元的 a[m][n] の行列表現 a11 a12 ・ a1n a21 1行目 2行目 m行目 a11 a12 ・・・ a1n a21 a22 a2n ・ am1 am2 amn 1行目 折り返し場所の情報は省略できない

12.2 2次元配列 プログラム例 12.2.1 #include <stdio.h> 12.2 2次元配列 プログラム例 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.2 2次元配列 プログラム例 12.2.2 2次元配列の1次元化(第2回)で 解決する方法もある 12.2 2次元配列 プログラム例 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"); 行数、列数を集中管理 2次元配列の1次元化(第2回)で 解決する方法もある

呼び出し側の配列へデータを返す c11 c12 c13 c21 c22 c23 c31 c32 c33 a11 a12 a13 プログラム例 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 に返すには?

呼び出し側の配列へデータを返す プログラム例 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] が入る

12.3 配列を使って結果を返す プログラム例 12.3.1 #include <stdio.h> #define NROW 3 12.3 配列を使って結果を返す プログラム例 12.3.1 #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 配列を使って結果を返す void sum(int x[][NCOL], int y[][NCOL], int z[][NCOL]) 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]) printf(" %10d", u[i][j]); printf("\n");

演習問題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 = ??????????????; 配列要素の数値の総和と 平均値を計算する関数 総和の計算 平均値の計算

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

演習問題12.3 (つづき) 行列の和 行列の差 行列の積 演習問題12.3 (つづき) void sum(int x[][N], int y[][N], int z[][N]) { ???...??? } void diff(int x[][N], int y[][N], int z[][N]) void prod(int x[][N], int y[][N], int z[][N]) 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[][N]) 行列の和 行列の差 行列の積

本日のパズル 次のプログラムは何を出力するか #include <stdio.h> #define PRINTX(f,x) printf("%"#f"\n",x) main() { int x=1, y=1; if( y<0 ) if( y>0 ) x=3; else x=5; PRINTX(d,x); if( x=y ); x=3; } 1 2