復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行

Slides:



Advertisements
Similar presentations
前回の関数のまとめ (1) プログラムは main() 関数の先頭から実行される 関数は main() 関数または他の関数から呼び出されて実行される. 関数を呼び出す側の実引数の値が関数内の仮引数 ( 変数 ) に コピーされる 関数内で求めた値は return 文によって関数値として呼び出し側に戻され.
Advertisements

復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
A B x y z 復習 構造体変数 普通の変数 x y z 構造体変数 x y z 箱のイメージ 引き出しのイメージ
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
ループで実行する文が一つならこれでもOK
プログラミング演習(1組) 第7回
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
基礎プログラミングおよび演習 第9回
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
第8回 プログラミングⅡ 第8回
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
構造体.
第7回 条件による繰り返し.
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
プログラミング2 関数
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
関数の定義.
第10回関数 Ⅱ (ローカル変数とスコープ).
Cプログラミング演習 第7回 メモリ内でのデータの配置.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
プログラミング入門2 第11回 情報工学科 篠埜 功.
今までの練習問題の復習.
同じ構造をした「引き出し」変数を構造体変数と呼ぶ
第7回 条件による繰り返し.
第9回関数Ⅰ (簡単な関数の定義と利用) 戻り値.
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
第11回 プログラミングⅡ 第11回
C#言語ソースプログラムの原型 C言語 C#言語 Hello World! Hello Students! オマジナイ! 適当なクラス名
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
復習 前回の関数のまとめ(1) プログラムはmain()関数の先頭から実行される
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
C言語 はじめに 2016年 吉田研究室.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング序論演習.
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
IF文 START もしも宝くじが当たったら 就職活動する 就職活動しない YES END NO.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
第5回 プログラミングⅡ 第5回
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
cp-3. 計算 (C プログラミング演習,Visual Studio 2019 対応)
プログラミング 4 文字列.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
知能情報工学演習I 第9回(後半第3回) 課題の回答
岩村雅一 知能情報工学演習I 第13回(後半第7回) 岩村雅一
プログラミング演習I 補講用課題
= 55 課題6-1 #define _CRT_SECURE_NO_WARNINGS
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行 float d[3][4]; 2次元配列 d[i][j] ⇒ 2つのインデックスiとjでデータが指定される 縦が3行 横が4列 のfloat型の表 横のインデックスは3まで j = 0 j = 1 j = 2 j = 3 4列 i = 0 i = 1 i = 2 3行 d[0][0] d[0][1] d[0][2] d[0][3] d[1][0] d[1][1] d[1][2] d[1][3] d[2][0] d[2][1] d[2][2] d[2][3] d[3][4]は存在しない 縦のインデックスは2まで

復習 2次元配列の初期化(2) 縦の行数は省略可 横の列数は省略不可 ⇒ 使用予定の最大の列数を指定する int aa[][] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; int aa[][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; 縦の行数は省略可 横の列数は省略不可 ⇒ 使用予定の最大の列数を指定する int aa[][4] = { {1, 2, 3, 4}, {5, 6}, {9, 10, 11} }; i = 0 i = 1 i = 2 j = 0 j = 1 j = 2 j = 3 この部分は0に初期化される 注意  int aa[3][4]; のように初期化しない配列の値は未定義 d[0][0] = 1 d[0][1] = 2 d[0][2] = 3 d[0][3] = 4 d[1][0] = 5 d[1][1] = 6 d[1][2] d[1][3] d[2][0] = 9 d[2][1] = 10 d[2][2] = 11 d[2][3] int aa[3][4]; aa[][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; 初期化は宣言と同時に!

2次元配列を用いたソースプログラムの例(3) 復習 改良型:縦の合計を出力 #include <stdio.h> main() { int aa[][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; int i, j, sum = 0; for (i = 0; i < 3; i++) // 配列内容を出力 for (j = 0; j < 4; j++) printf("%2d ", aa[i][j]); } printf("\n"); printf("==============\n"); for (j = 0; j < 4; j++) // 縦の合計を出力 sum = 0; for (i = 0; i < 3; i++) sum = sum + aa[i][j]; printf("%2d ", sum); d[0][0] = 1 d[0][1] = 2 d[0][2] = 3 d[0][3] = 4 d[1][0] = 5 d[1][1] = 6 d[1][2] = 7 d[1][3] = 8 d[2][0] = 9 d[2][1] = 10 d[2][2] = 11 d[2][3] = 12 1 2 3 4 5 6 7 8 9 10 11 12 ============== 15 18 21 24 続行するには何かキーを. . .

文字列の配列 4行 i = 0 i = 1 i = 2 i = 3 値が0 最後は0 ss[0] → "kandai" 'k' 'a' char ss[4][7] = { "kandai", "denki", "densi", "joho" }; i = 0 i = 1 i = 2 i = 3 j = 0 j = 1 j = 2 j = 3 j = 4 j = 5 j = 6 値が0 最後は0 ss[0] → "kandai" 'k' 'a' 'n' 'd' 'i' 'e' ‘n' 's' ‘i' 'j' 'o' 'h' ss[0][4] = 'a' 4行 ss[2] → "densi" ss[2][2] = 'n' ss[4]は無い 例えばss[0][4]はa,ss[2][2]はnという文字である. 横方向に見れば,ss[0]はkandai, ss[2]はdensiという文字列である. 続行するには何かキーを押してください . . . #include <stdio.h> main() { char ss[][7] = { "kandai", "denki", "densi", "joho" }; printf("例えばss[0][4]は%c,ss[2][2]は%cという文字である.\n", ss[0][4], ss[2][2]); printf("横方向に見れば,ss[0]は%s, ss[2]は%sという文字列である.\n", ss[0], ss[2]); } 行数は省略可 列数は省略不可. 最大文字数プラス1にする. 2つ目の[ ]を付けない.

文字列の配列を用いたプログラムの例 横方向の列数は最大文字数プラス1にする 文字列の配列のポイント int main(void) { char ss[4][31]; int i; for (i = 0; i < 4; i++) printf("%d人目の名前を入れてください(30文字まで):", i + 1); scanf("%s", ss[i]); } printf("入力された名前は次のとおりである\n"); printf("%d番 %-11s\n", i + 1, ss[i]); &と2つ目の[ ]を付けない. 普通,「0人目」とは言わないので,ここではプラス1しておいた %-11sで,「11桁で左詰め表示」となる(マイナス記号は左詰め指定) 2つ目の[ ]を付けない. 1人目の名前を入れてください(30文字まで):Matsushima 2人目の名前を入れてください(30文字まで):Abe 3人目の名前を入れてください(30文字まで):Putin 4人目の名前を入れてください(30文字まで):Obama 入力された名前は次のとおりである 1番 Matsushima 2番 Abe 3番 Putin 4番 Obama 続行するには何かキーを押してください . . . 文字列の配列のポイント ss[i][j]のようにインデックスを二つ指定した 場合は文字を表す ss[i]のようにインデックスを一つだけ指定した 場合は文字列を表す

文字列操作ライブラリを用いたソースプログラムの例 復習 文字列操作ライブラリを用いたソースプログラムの例 #include <stdio.h> #include <string.h> int main(void) { char ss1[] = "Kandai-sei", ss2[] = "Computer Science"; char ss3[100] = ""; //初めは空の文字列.十分な文字数を確保する. printf("ss1の文字数は%dですが,ss3の文字数は%dです.\n", strlen(ss1), strlen(ss3)); strcpy(ss3, ss1); //ss1の内容をss3にコピー printf("ss3の内容は%sになり,文字数は%dになりました.\n", ss3, strlen(ss3)); strcat(ss3, " / "); //ss3の最後に" / "を付加 strcat(ss3, ss2); //ss3の最後にss2を付加 printf("今度のss3は%sで,文字数は%dです.\n", ss3, strlen(ss3)); } 空の文字列として初期化することは重要! 配列なので,ss3=ss1という 代入はできない ss1の文字数は10ですが,ss3の文字数は0です. ss3の内容はKandai-seiになり,文字数は10になりました. 今度のss3はKandai-sei / Computer Scienceで,文字数は29です. 続行するには何かキーを押してください . . .

復習 文字列を操作するライブラリ関数の例 これらの文字列操作用ライブラリ関数を利用するには 意味 int strlen(char s[]) 文字列sの文字数を返す char* _strset(char s[], int c) 文字列sをアスキーコードcの文字で埋める char* strcpy(char s1[], char s2[]) 文字列s2を文字列s1にコピーする char* strcat(char s1[], char s2[]) 文字列s1の末尾に文字列s2を付加する int strcmp(char s1[], char s2[]) 文字列s1と文字列s2を比較する. 同じ文字列なら0を返す.辞書の順序で s1がs2より前なら,正の値を返す. s1がs2より後なら,負の値を返す. char*はポインタ.2年生で学習 これらの文字列操作用ライブラリ関数を利用するには  #include <string.h> が必要. 注1) 関数の表記は,現在の学習レベルに合わせて変更してある. 注2) 関数については第10回以降で詳しく学習.

関数の作成: なぜ自分で関数を作るのか? 長いプログラム 例えば,ソース500行 変数100個 プログラムの見通しが悪い 関数の作成: なぜ自分で関数を作るのか? 大規模なプログラムの例 長いプログラム 例えば,ソース500行 変数100個 #include <stdio.h> int main(void) { char err[] = "BMPOut"; int i, j; outpath = fname; if ((outfile = fopen(outpath, "wb")) == NULL) LW_ERROR(FILEOPEN, outpath); int Wx = w.right - w.left; int Wy = w.top - w.bottom; int Ox; if (Wx % 4 == 0) Ox = Wx; else Ox = (Wx/4 + 1)*4; // バッファー領域の確保 int imageSize = Ox * Wy; unsigned char* bmpimage = (unsigned char*) Malloc(sizeof(char)*Ox, err); BITMAPFILEHEADER bfh; bfh.bfType = ('M'<< 8)|'B'; bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256; bfh.bfSize = bfh.bfOffBits + imageSize; bfh.bfReserved1 = bfh.bfReserved2 = 0;   ewrite(&bfh, sizeof(bfh), 1);   BITMAPINFOHEADER bmih; bmih.biSize = sizeof(bmih); bmih.biWidth = Wx; bmih.biHeight = Wy; bmih.biPlanes = 1; bmih.biBitCount = 8; bmih.biCompression = BI_RGB; プログラムの見通しが悪い 後から見て理解できない 一つの修正が別の箇所に影響 → デバッグ困難 複数人で共同作業できない 大量の変数を用いる 変数名が重複する ある変数に関係する修正が他の変数に影響

同じ変数名aでもモジュールごとに異なった変数と見なされる.ローカル変数 注意 ここでは、機能単位の意味で「モジュール」という用語を用いているが、より専門的なソフトウェア工学では用語「モジュール」にはもっと厳密な定義がある。 プログラムのモジュール化 モジュール1 モジュール2 モジュール3 モジュール4 プログラム プログラムを小さな機能単位である モジュールに分割 モジュール内では見通しが良い 複数のプログラマーが異なったモジュールを担当できる(共同作業) モジュールを部品として再利用できる 各モジュールごとに変数名が独立 プログラム内で変数名が重複しない このようなモジュールを サブルーチンと呼ぶ int a; 同じ変数名aでもモジュールごとに異なった変数と見なされる.ローカル変数

プログラムのモジュール例 プログラムA データ入力モジュール モジュール1 モジュール2 平均値計算モジュール プログラムB モジュール3 結果の表示 データ入力モジュール scanf()を用いて配列に100個までのデータを入力する 平均値計算モジュール 配列の値の平均値を求める プログラムB モジュール1 モジュール2 モジュール3 結果の表示 モジュール4 最大値計算モジュール 配列の値の最大値を求める 確率誤差計算モジュール 配列の値とその平均値から確率誤差を求める 画面表示モジュール 配列の値を綺麗に画面表示する

C言語のおける機能単位(モジュール) = 関数 #include <stdio.h> #include <math.h> int main(void) { double x, y; scanf(‶%lf‶, &x); y = sqrt(x); printf(‶%e‶, y); } 入力をする関数 出力をする関数 平方根を求める関数 プログラムは関数の組み合わせでできている! 自分で作ったプログラムをモジュール化するにはどうするか? ⇒ 関数を自分で作る!

底辺aで高さbの三角形の面積を求める関数 関数とは何か? 底辺aで高さbの三角形の面積を求める関数 数学の場合 三角形の面積を表す関数 関数値を代入 引数の代入 もしも 底辺3 [cm]で, 高さ4 [cm]なら プログラミングでは・・・ 変数には型がある  →変数が文字や配列の場合もある 関数値の代入でも型が重要  →関数値が文字や配列の場合もある sは6 [cm2]になる

プログラムは必ずmain()関数の先頭から実行される Cにおける関数の宣言と呼び出し(1) 関数値の型 関数の定義 (実行ではない) #include <stdio.h> float menseki(float a, float b) { float s; s = a * b / 2; return s ; } int main(void) float kekka; printf("面積を求めます.\n"); kekka = menseki(3, 4); printf("面積は%fです.\n", kekka); 引数の代入 引数の型と名前 ローカル変数 (関数内でのみ有効) 関数の名前 関数値の代入 !注意! プログラムは必ずmain()関数の先頭から実行される 関数の呼び出し (関数の実行)

関数定義におけるreturn 文 float menseki(float a, float b) { float s; s = a * b / 2; return s; } float menseki(float a, float b) { return a * b / 2; } return文の文法  return 式; return文を実行すると関数を終了する.式で計算した値を返す. int func(int x, int y) { if (x*y % 2 == 0) return 1; } return文を実行しない場合があるのでダメ. int func(int x, int y) { if (x*y % 2 == 0) return 1; } else return 0; return文は複数あってもOK.但し,どのような場合でも必ずその一つを実行すること. return文で返る値を返却値,返り値あるいは戻り値と呼ぶ

printf("面積は%fです.\n", menseki(x, y)); でもOK Cにおける関数の宣言と呼び出し(2) #include <stdio.h> float menseki(float a, float b) { return a * b / 2; } int main(void) float x, y, kekka; printf("底辺は?"); scanf("%f", &x); printf("高さは?"); scanf("%f", &y); kekka = menseki(x, y); printf("面積は%fです.\n", kekka); a, b: 仮引数 仮引数もローカル変数 →関数内でのみ有効 x,y:実引数 printf("面積は%fです.\n", menseki(x, y)); でもOK

menseki()関数内のローカル変数aとb ローカル変数(1) #include <stdio.h> float menseki(float a, float b) { float s; s = a * b / 2; return s; } int main(void) float a, b, kekka; printf("底辺は?"); scanf(" %f ", &a); printf("高さは?"); scanf(" %f ", &b); kekka = menseki(); printf("面積は%fです.\n", kekka); menseki()関数 menseki()関数内のローカル変数aとb ローカル変数 同じ変数名a, bでも,関数が違うと,別の変数と見なされる ⇒赤色a,bと青色a,bは別の変数 main()関数 main()関数内のローカル変数aとb

変数kekkaはmain()関数中でのみ使える ローカル変数(2) #include <stdio.h> float menseki(float a, float b) { kekka = a * b / 2; } int main(void) float a, b, kekka; printf("底辺は?"); scanf(" %f ", &a); printf("高さは?"); scanf(" %f ", &b); menseki(a,b); printf("面積は%fです.\n", kekka); 関数menseki()内ではkekkaという変数は定義されていない  ⇒ エラー! 変数kekkaはmain()関数中でのみ使える 変数は,それを宣言した関数内でのみ有効

プログラムのモジュール化(関数化)のススメ ダメプログラマAさん 優秀プログラマBさん #include <stdio.h> int main(void) {   float a, b, x[100]; int i, j, n;   ・・・ //データ入力 for (i = 0; i < n; i++) scanf(" %f ", &a); ・・・ //データ処理 //結果出力 printf("面積は%fです.\n", kekka); } #include <stdio.h> int Input(float x[]) { ・・・ } int Calculation(float x[], int n) int Output(float x[], int n) int main(void) Input() //データ入力 Calculation() //データ処理 Output() //結果出力 機能ごとにくっきりと関数(モジュール)分け 全ての処理がmain()関数にダラダラ書かれている main()関数は短くすっきり