A B x y z 復習 構造体変数 普通の変数 x y z 構造体変数 x y z 箱のイメージ 引き出しのイメージ

Slides:



Advertisements
Similar presentations
1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放.
Advertisements

構造体変数 1234 x xyz A 普通の変数 ( ここでは座標値 ) 構造体変数 ( ここでは点を表す ) xyz B 14 y 5 z 点 A の x 座標 プログラム中では A.x 点 B の y 座標 プログラム中では B.y 例えば 「 3 次元空間で2点 A と B の 間に線分を引き・・・」
前回の関数のまとめ (1) プログラムは main() 関数の先頭から実行される 関数は main() 関数または他の関数から呼び出されて実行される. 関数を呼び出す側の実引数の値が関数内の仮引数 ( 変数 ) に コピーされる 関数内で求めた値は return 文によって関数値として呼び出し側に戻され.
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
次ページに関数の解答例 課題12-1 (問題と解答) 複素数xとして, 実部を入力してください.10 虚部を入力してください.20
復習 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行
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
初年次セミナー 第4回 整数と実数の取り扱い.
1.1 C/C++言語 Hello.ccを作りコンパイルしてa.outを作り出し実行する
第2章 数値の入力と変数 scanfと変数をやります.
第13回構造体.
第12回構造体.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
構造体.
第10回 プログラミングⅡ 第10回
情報基礎及び演習 プログラミング基礎① 電気・佐藤亮一.
第2回 Microsoft Visual Studio C++ を使ってみよう
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
Cプログラミング演習 第7回 メモリ内でのデータの配置.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
今までの練習問題の復習.
前回の練習問題.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
同じ構造をした「引き出し」変数を構造体変数と呼ぶ
第9回関数Ⅰ (簡単な関数の定義と利用) 戻り値.
第7回 プログラミングⅡ 第7回
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
知能情報工学演習I 第8回( C言語第2回) 課題の回答
地域情報学 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行
プログラミング基礎B 文字列の扱い.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
復習 前回の関数のまとめ(1) プログラムはmain()関数の先頭から実行される
C言語 はじめに 2016年 吉田研究室.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
プログラミング演習I 2003年4月30日(第3回) 木村巌.
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
第5回 プログラミングⅡ 第5回
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
標準入出力、変数、演算子、エスケープシーケンス
知能情報工学演習I 第8回(後半第2回) 課題の回答
プログラミング 4 文字列.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
モバイルプログラミング第2回 C言語の基礎 (1).
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
printf・scanf・変数・四則演算
第2章 数値の入力と変数 scanfと変数をやります.
知能情報工学演習I 第9回(後半第3回) 課題の回答
復習 いろいろな変数型(2) char 1バイト → 英数字1文字を入れるのにぴったり アスキーコード → 付録 int
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

A B x y z 1234 14 5 復習 構造体変数 普通の変数 x y z 構造体変数 x y z 箱のイメージ 引き出しのイメージ 例えば 「3次元空間で2点AとBの間に線分を引き・・・」 実際には点Aや点Bは座標で表すので,複数の変数が必要 復習 構造体変数 箱のイメージ 1234 x 14 y 5 z 普通の変数 (ここでは座標値) x y z A 構造体変数 (ここでは点を表す) 引き出しのイメージ 点Aのx座標 プログラム中では A.x x y z B 点Bのy座標 プログラム中では B.y

復習 a b 構造体のプログラム例(1) ー 日付型 キーワード struct 構造体内の変数をメンバ変数と呼ぶ 2 構造体のプログラム例(1) ー 日付型 キーワード struct 構造体内の変数をメンバ変数と呼ぶ #include <stdio.h> struct Date { int year; int month; int day; }; void main() Date a, b; a.year = 2015; a.month = 7; a.day = 1; b = a; b.day = 2; printf("初めの日付は%d年%d月%d日,", a.year, a.month, a.day); printf("次の日付は%d年%d月%d日\n", b.year, b.month, b.day); } Date型の構造体の定義 Dateは変数ではなく設計図 year month day a 2015 7 1 year month day b 2015 7 2 1 Date型の構造体変数 aとbの宣言 a.year は構造体変数aのメンバ変数yearを意味する 構造体変数aをbに代入 b.day は構造体変数bのメンバ変数dayを意味する 初めの日付は2015年7月1日,次の日付は2015年7月2日

構造体と配列を組み合わせたプログラム例(1/2) 復習 構造体変数の中に配列が含まれている場合(配列を含む構造体) 構造体変数が配列になっている場合(構造体変数の配列) #include <stdio.h> struct BaitoKanri //バイト管理構造体 { int id; //バイトの個人番号 char name[20]; //バイトの氏名(文字列) int money[12]; //1~12月に支払ったバイト料(1000円単位) }; // バイト一人分の番号,氏名,支払額の表示する関数 void PrintPerson(BaitoKanri baito) int i; printf("%2d %-10s", baito.id, baito.name); for (i = 0; i < 12; i++) printf(" %2d", baito.money[i]); } // バイト一人分の1年間の支払額を計算する関数 int Sum(BaitoKanri a) int i, sum = 0; sum = sum + a.money[i]; return sum; 配列を含む構造体の定義 この構造体にバイト一人あたりの情報をすべて詰め込んで管理する この関数を使うと構造体変数baitoの(一人分の)情報を画面表示できる この関数は,構造体変数aの(一人分の)1年間の給料総額を返す 番号 氏名 毎月の給料(単位:千円) 合計 -------------------------------------------------------- 10 Matsushima 10 15 12 10 15 20 20 15 11 15 12 10 : 165 15 Noda 10 15 14 20 15 20 20 16 11 15 42 10 : 208 16 Obama 20 15 13 15 15 30 20 15 11 25 12 10 : 201 20 Putin 12 15 12 20 15 20 10 17 11 15 12 10 : 169 続行するには何かキーを押してください . . .

構造体と配列を組み合わせたプログラム例(2/2) 復習 構造体と配列を組み合わせたプログラム例(2/2) #include <stdio.h> struct BaitoKanri //バイト管理構造体 { int id; //バイトの個人番号 char name[20]; //バイトの氏名(文字列) int money[12]; //1~12月に支払ったバイト料(単位1000円) }; 一人分の情報 構造体変数の配列宣言 int main(void) { BaitoKanri list[4] = { {10, "Matsushima", {10, 15, 12, 10, 15, 20, 20, 15, 11, 15, 12, 10}}, {15, "Noda", {10, 15, 14, 20, 15, 20, 20, 16, 11, 15, 42, 10}}, {16, "Obama", {20, 15, 13, 15, 15, 30, 20, 15, 11, 25, 12, 10}}, {20, "Putin", {12, 15, 12, 20, 15, 20, 10, 17, 11, 15, 12, 10}}, }; printf("番号 氏名 毎月の給料(単位:千円) 合計\n"); printf("---------------------------------------------------------\n"); int i; for (i = 0; i < 4; i++) PrintPerson(list[i]); printf(" :%4d\n", Sum(list[i])); } ここでは4人分の情報で初期化 番号 氏名 毎月の給料(単位:千円) 合計 -------------------------------------------------------- 10 Matsushima 10 15 12 10 15 20 20 15 11 15 12 10 : 165 15 Noda 10 15 14 20 15 20 20 16 11 15 42 10 : 208 16 Obama 20 15 13 15 15 30 20 15 11 25 12 10 : 201 20 Putin 12 15 12 20 15 20 10 17 11 15 12 10 : 169 続行するには何かキーを押してください . . . list[i]は,i番目の一人分の情報(一つの構造体変数) これは配列引数ではないことに注意!

関数のプロトタイプ宣言(1) 呼出し 定義 呼出し 定義 ソースプログラム上で,関数の定義は関数の呼出しより先に書かれていなければならない #include <stdio.h> float menseki(float a, float b) { float s; s = a * b / 2; return s; } int main(void) float kekka; kekka = menseki(3, 4); printf("s=%f\n", kekka); #include <stdio.h> int main(void) { float kekka; kekka = menseki(3, 4); printf("s=%f\n", kekka); } float menseki(float a, float b) float s; s = a * b / 2; return s; 呼出し 定義 呼出し 定義 ソースプログラム上で,関数の定義は関数の呼出しより先に書かれていなければならない 理由:コンパイラはソースプログラムの先頭から順にソースプログラムを機械語に変換するため,関数の定義より先に関数の呼び出しがあると機械語に変換できない.

関数のプロトタイプ宣言(2) 定義 定義 呼出し 定義 呼出し 呼出し 関数がお互いに呼び出しあうソースプログラムは記述不可能?? #include <stdio.h> float func1(...) //何かの関数1 { ... b = func2(...); return s; } void func2(...) //何かの関数2 c = func1(...); return; int main(void) x = func1(...); y = func2(...); #include <stdio.h> void func2(...) //何かの関数2 { ... c = func1(...); return; } float func1(...) //何かの関数1 b = func2(...); return s; int main(void) x = func1(...); y = func2(...); 定義 定義 呼出し 呼出し 定義 呼出し 関数がお互いに呼び出しあうソースプログラムは記述不可能??

printf()関数やscanf()関数では 不要? 関数のプロトタイプ宣言(3) #include <stdio.h> float menseki(float a, float b); int main(void) {   float kekka;   kekka = menseki(3, 4);   printf("s=%f\n", kekka); } float menseki(float a, float b)   float s;   s = a * b / 2;   return s; ソースプログラム上で,関数の呼び出し前に,関数の定義か,プロトタイプ宣言のどちらかが絶対必要 関数のプロトタイプ宣言 printf()関数やscanf()関数では 不要? 呼出し No! 絶対必要 定義 printf()やscanf()のプロトタイプ宣言はstdio.hファイルに定義されている. プロトタイプ宣言は関数定義の予告編 プロトタイプ宣言 = 関数定義の1行目 プロトタイプ宣言は関数の使用方法(引数の数と型,戻り値の型)を示している

→ stdio.hという名前のヘッダファイルを読み込む 関数のプロトタイプ宣言を集めてあるファイル → ヘッダファイル (xxxxx.h) ヘッダファイルをソースプログラム内に読み込む命令 → #include #include <stdio.h> → stdio.hという名前のヘッダファイルを読み込む ライブラリ関数 stdio.h あらかじめ用意されている標準入出力関数であるprintf()やscanf()などのプロトタイプ宣言が書かれているヘッダファイル (standard input output) math.h sqrt()などの数値計算関数のヘッダファイル (mathematics) 疑問:ライブラリ関数のプロトタイプ宣言はヘッダファイルに書かれている. では関数本体の定義はどこにある?

実行プログラムができるまで ライブラリ関数 #include コンパイル コンパイル 済みの本体 リンク ソースプログラム ヘッダファイル (source13-1.cpp) 実行プログラム (kadai13-1.exe) コンパイラ 機械語への変換 .exeファイルだけでプログラムが実行できる! プロジェクト名  kadai13-1 ソースプログラム名  source13-1.cpp プロジェクトフォルダ内のDebugまたはReleaseフォルダにできる #include ヘッダファイルの読み込み オブジェクトファイルを結合(リンク) する コンパイル 済みの本体 オブジェクトファイル (ライブラリファイル) ヘッダファイル (プロトタイプ宣言) ライブラリ関数 コンパイル リンク コンパイル+リンク=ビルド と呼んでいる ソースプログラム2 ソースプログラム3 ソースプログラム4 オブジェクトファイル2 オブジェクトファイル3 オブジェクトファイル4 コンパイラ 参考:複数のソースプログラムがある場合 プリプロセス(事前処理) されたソースプログラム オブジェクトファイル (source13-1.obj) プリプロセッサ リンカ ヘッダファイルの読み込み等の処理 ライブラリとオブジェクトファイルの結合 複数のオブジェクトファイルの結合 ※ここでのオブジェクトファイルは 構造体で学習した「オブジェクト」とは異なる

プリプロセッサ命令 #include <標準ヘッダファイル名> #include "自作ヘッダファイル名" プリプロセッサ命令は #で始まる #include <標準ヘッダファイル名> #include "自作ヘッダファイル名" #define マクロ名  マクロ文字列 ヘッダファイルを読み込む マクロ名をマクロ文字列で置き換える スペース(空白)またはタブ ソースファイル:kadai12.cpp void func1(int a); float func2(int a, float b); int main(void) { int x,y; x = 35 + 22 + 'B'+15; func1(x); y = func2(35, 'B'+15); } プリプロセッサの処理後 プリプロセス #include "rei12.h" #define teisu 35 #define moji 'B'+15 int main(void) { int x,y; x = teisu + 22 + moji; func1(x); y = func2(teisu, moji); } 自作ヘッダファイル:rei12.h コンパイル void func1(int a); float func2(int a, char b);

プリプロセッサ命令を用いたプログラムの例(1) x = 0.000, sin x = 0.000 x = 0.314, sin x = 0.309 x = 0.628, sin x = 0.588 x = 0.942, sin x = 0.809 x = 1.257, sin x = 0.951 x = 1.571, sin x = 1.000 x = 1.885, sin x = 0.951 x = 2.199, sin x = 0.809 x = 2.513, sin x = 0.588 x = 2.827, sin x = 0.309 x = 3.142, sin x = 0.000 x = 3.456, sin x = -0.309 x = 3.770, sin x = -0.588 x = 4.084, sin x = -0.809 x = 4.398, sin x = -0.951 x = 4.712, sin x = -1.000 x = 5.026, sin x = -0.951 x = 5.341, sin x = -0.809 x = 5.655, sin x = -0.588 x = 5.969, sin x = -0.309 x = 6.283, sin x = -0.000 続行するには何かキー. . . x=0から2まで/10毎にsin xを計算する #include <stdio.h> #include <math.h> #define PI 3.1415 int main(void) { double x; for (x = 0; x <= 2*PI; x = x + PI/10) printf("x = %5.3f, sin x = %6.3f\n", x, sin(x)); }

標準ライブラリ関数を用いたプログラムの例(2) 10文字 (= amp) y=0 ⇒ s[10] s[20] ⇑ y=1.0 y=-1.0 ⇓ s[0] 21文字の文字列s[]で1文字だけを'*'にして,グラフとして表現する x y #include <stdio.h> #include <math.h> #include <string.h> #define PI 3.1415 #define amp 10 int main(void) { double x, y; int p; char s[2*amp + 2]; s[2*amp + 1] = 0; for (x = 0; x <= 2*PI; x = x + PI/10) _strset(s, ' '); y = sin(x); p = (int)(amp * y + amp + 0.5); s[p] = '*'; printf("%s\n", s); } * 続行するには何かキー. . . 要素数22の配列宣言 注) ampが10に置き換えられてからコンパイルされるので,エラーにならない 文字列なので最後(S[21])は0にしておく 文字列sを全て特定の文字(ここでは空白文字)で埋めるライブラリ関数 y = sin xのy値からどの文字を*に変えるかを計算

どの文字を’*’に変更するのか? (変更する文字の位置の求め方の説明) y = sin x y = -1 y = 0 y = +1 s[22] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21個の要素の いずれかを '*'文字にする p=0 p=10 p=20 double型 int型 p = 10 * y + 10 y : sin(x)の計算結果(double型) p : 文字列sで*印を入れる位置のインデックス(int型)

キャストによる変数型の変換 x1 = 0.00, x2 = 0.00 y1 = 0.33, y2 = 0.67 続行するには何かキー. . . #include <stdio.h> int main(void) { int a = 2, b = 3; double x1, x2, y1, y2; x1 = 1 / 3; x2 = a / b; printf("x1 =%5.2f, x2 =%5.2f\n", x1, x2); y1 = 1.0 / 3; y2 = (double) a / b; printf("y1 =%5.2f, y2 =%5.2f\n", y1, y2); } 整数同士の演算では少数以下は切り捨て 1/3 = 0.333… ⇒ 0 整数変数同士の演算でも少数以下切り捨て 浮動小数点と整数の演算では全て浮動小数点として計算 1.0/3 = 1.0/3.0 ⇒ 0.333… 整数変数同士の演算だが,浮動小数点で計算させたい キャストの書き方 (変数型) 変数 変数を変数型に変換する キャストによる型の変換

キャストを用いた四捨五入 #include <stdio.h> int main(void) { int c0, c1, c2, c3, c4; double x1, x2; x1 = 3.4999; c0 = x1; c1 = (int) x1; x2 = 3.5000; c2 = (int) x2; printf("c1 = %d, c2 = %d\n", c1, c2); c3 = (int) (x1 + 0.5); c4 = (int) (x2 + 0.5); printf("c3 = %d, c4 = %d\n", c3, c4); } c1 = 3, c2 = 3 c3 = 3, c4 = 4 続行するには何かキー. . . warning C4244: '=' : 'double' から 'int' への変換です。データが失われる可能性があります。 キャストを用いているので警告が出ない! キャストを用いた四捨五入 0.5を足して整数型に変換すると小数以下の四捨五入になる 3.4999 + 0.5 = 3.9999 ⇒ 3 3.5000 + 0.5 = 4.0000 ⇒ 4

標準ライブラリ関数を用いたプログラムの例(2) 10文字 (= amp) y=0 ⇒ s[10] s[20] ⇑ y=1.0 y=-1.0 ⇓ s[0] 21文字の文字列s[]で1文字だけを'*'にして,グラフとして表現する x y #include <stdio.h> #include <math.h> #include <string.h> #define PI 3.1415 #define amp 10 int main(void) { double x, y; int p; char s[2*amp + 2]; s[2*amp + 1] = 0; for (x = 0; x <= 2*PI; x = x + PI/10) _strset(s, ' '); y = sin(x); p = (int)(amp * y + amp + 0.5); s[p] = '*'; printf("%s\n", s); } * 続行するには何かキー. . . p = 10 * y + 10 ↓ p = (int)(10 * y + 10 + 0.5)