情報処理Ⅱ 2007年12月10日(月).

Slides:



Advertisements
Similar presentations
構造体 構造体とは? 複数のデータをパックしたもの。 新しい “ 型 “ として使用できる. 構造体 キーワード struct strcut は構造体を宣言する命令。 struct { double x,y; }a,b,c; ↑ ここまでが宣 言 ← この形式で、構造体 a,b,c, を定 義.
Advertisements

アルゴリズムとデータ構造 第2回 線形リスト(復習).
情報処理Ⅱ 第11回 2004年12月21日(火).
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
情報処理Ⅱ 第10回 2004年12月14日(火).
プログラミング言語としてのR 情報知能学科 白井 英俊.
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
第12回新しい型と構造体.
第13回構造体.
ファーストイヤー・セミナーⅡ 第8回 データの入力.
第12回構造体.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
情報処理Ⅱ 2005年12月9日(金).
第8回 プログラミングⅡ 第8回
プログラミング実習 1・2 クラス 第 1 週目 担当教員:  渡邊 直樹.
アルゴリズムとデータ構造 2011年6月13日
構造体.
プログラミング演習II 2004年12月 21日(第8回) 理学部数学科・木村巌.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
情報処理Ⅱ 第4回 2007年10月29日(月).
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
第10回 プログラミングⅡ 第10回
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
情報処理Ⅱ 2007年11月5日(月).
情報処理Ⅱ 第2回 2007年10月15日(月).
第11回 宿題 出題日:12月21日 締切日:1月7日(木).
Cプログラミング演習 第7回 メモリ内でのデータの配置.
精密工学科プログラミング基礎 第10回資料 (12/18実施)
プログラミング 4 記憶の割り付け.
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
プログラミング演習I 2003年5月7日(第4回) 木村巌.
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
第11回 プログラミングⅡ 第11回
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
フロントエンドとバックエンドのインターフェース
情報処理Ⅱ 第2回:2003年10月14日(火).
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
精密工学科プログラミング基礎Ⅱ 第5回資料 今回の授業で習得してほしいこと: 構造体 (教科書 91 ページ)
構造体と共用体.
データ構造とアルゴリズム 第11回 リスト構造(1)
アルゴリズムとプログラミング (Algorithms and Programming)
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
ポインタとポインタを用いた関数定義.
情報処理Ⅱ 2006年12月15日(金).
アルゴリズムとデータ構造 2012年6月11日
情報処理Ⅱ 第2回 2005年10月14日(金).
情報処理Ⅱ 第2回 2006年10月13日(金).
アルゴリズムとデータ構造1 2009年6月15日
ネットワーク・プログラミング Cプログラミングの基礎.
第5回 プログラミングⅡ 第5回
情報処理Ⅱ 2005年10月28日(金).
オブジェクト指向言語論 第二回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2010年6月17日
情報処理Ⅱ 2006年11月8日(金).
情報処理Ⅱ 2005年12月16日(火).
情報処理Ⅱ 第2回 2004年10月12日(火).
情報処理Ⅱ 2005年11月25日(金).
プログラミング演習II 2003年11月19日(第6回) 木村巌.
プログラミング演習II 2003年12月10日(第7回) 木村巌.
プログラミング入門2 第5回 配列 変数宣言、初期化について
情報処理Ⅱ 小テスト 2005年2月1日(火).
C言語講座第5回 2017 構造体.
情報処理Ⅱ 2006年10月27日(金).
情報処理Ⅱ 第8回:2003年12月9日(火).
Presentation transcript:

情報処理Ⅱ 2007年12月10日(月)

自分の思う通りに,適切な形で,プログラムとして表現する. 授業の進め方 構造体 その他の型 2年以降で さらに学習・習熟 プリプロセッサ 指令 ライブラリ関数 ファイル入出力 自分の思う通りに,適切な形で,プログラムとして表現する. 配列・文字列 ポインタ 関数 変数の 有効範囲 識別子 算術型 再帰呼び出し 制御文 演算子 プログラムの作成・ コンパイル・実行

本日学ぶこと いくつかの型 なぜ「型」にこだわるか? 以下を読む上での注意 typedef 列挙型(enum型) 構造体 処理対象のデータを効果的・効率的に取り扱える 既存の機能をもとに,便利な機能を創れる 以下を読む上での注意 この色とこの色は型名を表す. この色は変数名を表す. プログラムを書きやすく 読みやすくする…定性的なメリット 実行時のコスト(メモリ使用量など)を見積もることができ,そこからプログラムの改善が期待できる…定量的なメリット リpp.108-109

typedef 独自に型(type)を定義(define)する. 例 構造体の型名定義によく用いられる. ただし,メモリに割り当てるわけでないので,「宣言」である. 例 typedef signed char schar; schar c; ⇒ signed char c; と同じ typedef unsigned char uchar; uchar c, *p; ⇒ unsigned char c, *p; と同じ typedef char *String; String s, t; ⇒ char *s, *t; と同じ typedef char c5[5]; c5 x, y, z; ⇒ char x[5], y[5], z[5]; と同じ 構造体の型名定義によく用いられる. リp.107, pp.142-145

typedefの考え方 変数の定義 型の定義 char c5[5]; は,変数c5を定義し,その型はchar [5]型とする.

列挙型(enumeration)とは 「ラベル」を格納・参照・比較したいときに使う. 構文: enum タグ名 { 列挙子並び }; 変数に格納される具体的な値には関心がない. 実際には,ラベルに整数値が割り当てられる.これを積極的に活用することもある. 構文: enum タグ名 { 列挙子並び }; 「enum タグ名」型が定義される. 列挙子は「,」で区切る. リpp.65-66, p.138

列挙型の使用例 1 例 enum Boolean {FALSE, TRUE}; enum Boolean p = TRUE, q = FALSE, r = p||q; enum month {   Jan = 1, Feb, Mar, ..., Dec, MONTH_END } mloop; int rain[100][MONTH_END]; for (mloop = Jan; mloop < MONTH_END; mloop++) {   rain[7][mloop] = ...; } 13 型と変数を同時に定義 年月単位の降水量を格納する

汎整数型 汎整数型(integral type)に含まれるもの 列挙型は,計算時にはint型とみなされる. 整数型(char,int,long など) 列挙型 size_t型(sizeof演算子の評価値など.unsigned intまたはunsigned longと同一のことが多い.) 列挙型は,計算時にはint型とみなされる. ただし,利用は代入,比較,範囲内の増分・減分にとどめておく. リp.64

構造体(structure) 複数のオブジェクトを取りまとめて一つのオブジェクトとして扱うための機構 構造体で表現するとよいもの (2次元,3次元などの)座標上の点 複素数 行列(行数と列数と各成分) 所持金 学生情報 (x,y) 500 50 100 10 学生番号:0001 氏名:和大太郎 情報処理Ⅰの成績:80 情報処理Ⅱの成績:75 修得単位数: 52 入p.242 リp.366

構造体宣言の例(1) 構文: struct タグ名 { メンバ宣言子並び }; 例 「struct タグ名」型が定義される. struct point { double x; double y; }; struct point p = {1, -1}; セミコロンを忘れない ように この x と y を, point構造体の メンバという. x = 1 y = -1 p: 配列と同じ書式で 初期化可能 リpp.366-367, pp.205-206

構造体宣言の例(2) 構造体宣言と変数定義を一つの文で 構造体宣言と型定義を一つの文で struct point { double x; double y; } p; 構造体宣言と型定義を一つの文で typedef struct Point { double x, y; } point; point p; 「,」を用いて メンバを一括 宣言してよい 構造体宣言と型定義とを同時に行った場合, struct Point型とpoint型とで相互に参照・代入してよい. C++では,「構造体のタグ名」と「型名」が重複するとエラーとなる. リp.367の例でも,別にしている. typedefは,「structとタイプするのを減らす」ためではなく,「構造体であることを見えなくする」ために使用すべきである. struct Point型と point型が定義される 入p.242 リpp.367-368

構造体宣言の例(3) 無名構造体 struct { double x; double y; } p; typedef struct { double x, y; } point; point p; 無名構造体として定義した変数は,そのメンバへのアクセスはできるが, 関数呼び出しの引数としては使用できない(どんな型か,コンパイラは分からない). typedef struct {略} point; と定義した場合,その型のオブジェクト同士では参照や代入ができるが, 前のページのstruct point型と相互に(構造体として)代入することは,できない.

構造体宣言の例(4) 行列(行数,列数とも10まで) 行列(成分はポインタ) struct matrix { row column int row, column; double element[10][10]; }; 行列(成分はポインタ) double **element; row column element … row column element 上の構造体について, rowとcolumnは,コンパイラが参照するためのラベルであると同時に, この構造体のオブジェクトを定義すると,それぞれの値を格納する領域もメモリ上に確保される. elementは,コンパイラが参照するためのラベルであるが,メモリ上には確保されない. elementが参照する二次元配列領域は,メモリ上に確保されるが,elementを介することなく, 直接各要素の値を獲得したり,書き換えたりすることはできない. 下の構造体について,行列の各要素は,構造体オブジェクトの外で確保することになる.

構造体宣言の例(5) 自己参照構造体 struct node { graph … label = 'A' label = 'Z' next char label; struct node *next; }; struct node graph[100]; graph[0].label = 'A'; graph[0].next = graph + 1; graph[1].label = 'Z'; graph[1].next = NULL; graph … label = 'A' label = 'Z' next next = NULL 自己参照構造体が定義できるのは, メンバnextの型が(自己参照する)構造体そのものではなくそのポインタだから. 専門用語を用いると,nextの型を決定する時点では「struct node」型が「不完全型」として利用可能となっていて, 型定義の「};」を終えたところで,「struct node」型は「構造体型」とみなされる. そもそも,どのようにメモリに構造体オブジェクトを作ればよいかを考えると, メンバが,自己参照する構造体そのものではまずい(その型が定義できて, 変数も確保できたとして,sizeof(変数)が計算できる?). ここで問題.無名構造体かつ自己参照構造体という型を作ることはできるか? リp.69, p.143, p.372, p.376

構造体の参照と代入(1) 前提 メンバへのアクセス方法 struct point { double x, y; }; struct point p, *pp = &p; メンバへのアクセス方法 構造体オブジェクトpのメンバxは p.x と書いて 参照・代入ができる. 構造体オブジェクトを指し示すポインタppについては,(*pp).x もしくは pp->x と書けばよい. . と -> は演算子であり,最上位の優先順位を持つ. x y p: pp × *pp.x 入p.243 リp.157, pp.367-368

構造体の参照と代入(2) 構造体オブジェクトの代入 構造体渡し struct matrix a, b; (aを初期化) b = a; とすると,bにはaのコピーが格納される. 構造体の中に配列があっても,コピーされる. 構造体の中のポインタは,ポインタ値がコピーされる. 構造体渡し 関数の引数や戻り値の授受でも,構造体オブジェクトが代入(コピー)される. しかし,構造体はしばしばポインタで渡される(参照渡し). 関数処理で,構造体オブジェクトの中の値を変えたいとき 大きなサイズの構造体オブジェクトをスタックに置きたくないとき リp.163, p.358, pp.97-98

三角形の面積:仕様 2次元座標上の三角形の面積を求める. 構造体を用いる. 三点P(a, b), Q(c, d), O(0,0)からなる⊿PQOの面積は,|ad-bc|/2 で求められることを利用する. y http://d.hatena.ne.jp/takehikom/20061021/1161379979 http://www004.upp.so-net.ne.jp/s_honma/heron/heron.htm O x

三角形の面積:構造体 2次元座標の点 三角形の3点 メンバと変数は,識別子が重複していてもよい. struct point { double x, y; }; 三角形の3点 struct triangle { struct point p1, p2, p3; メンバと変数は,識別子が重複していてもよい. リp.103

三角形の面積:関数 struct triangle transform_triangle(struct triangle t); 三角形の3点を,メンバp3が原点になるように平行移動する. double calc_area(struct triangle t); 三角形の面積を求める. y y p1(1,3) p1(-3,1) p3(4,2) p3(0,0) O x O p2(5,0) x p2(1,-2)

構造体利用時の注意 構造体と配列の使い分け sizeof(構造体) 構造体とプログラミング してはいけないこと

構造体と配列の使い分け 配列 構造体 「配列を含む構造体」や「構造体の配列」もよく利用される. 同一の型の集まり 各要素に番号がついている ループなどを使って順番に処理する 構造体 様々な型の集まり(ただし,同一の型の集まりでもよい) 各要素に付けられた名前を使ってアクセスする 「配列を含む構造体」や「構造体の配列」もよく利用される. 入p.244

sizeof(構造体) sizeof(構造体) は,構造体の各メンバのサイズの合計以上になる. 構造体オブジェクトの中で使用されない領域もあり得る.「パディング」または「穴」と呼ばれる. s: c i パディング struct s { char c; int i; }; sizeof(char) == 1 sizeof(int) == 4 でも sizeof(struct s) != 5 リp.373

構造体とプログラミング さまざまな種類の情報を持つ「実体」を一つのオブジェクトとして処理したいとき, まず,「何に処理をしたいか?」を考える. 保持すべき情報を細分化し,それぞれをメンバとするような構造体を宣言する. 次に,「何の処理をしたいか?」を考える. 構造体を引数にとって処理する関数を定義する. 引数・戻り値ともに,型は構造体そのものにすべきか, 構造体のポインタにすべきか,そのつど検討する. 動作確認用に,構造体の中身を出力する関数も.

してはいけないこと × 関数内のauto変数を指し示すポインタを,戻り値とする. struct point *create_point(int x, int y) {   struct point p = {x, y}; return &p; } コンパイルエラーにはならないが,実行時に支障をきたす. 関数処理が終わると,pの領域が破棄される ⇒ *(&p)が不定! pをstatic変数とするか,mallocで実行時に領域を確保してそのポインタを返せば,問題を回避できる. リpp.118-119

独自の型はどこで定義する? 一般には,グローバル区間で定義し,複数の関数間で利用できるようにする. ブロックの中で定義してもよい. #include文の後ろ,関数プロトタイプの前に書く. ブロックの中で定義してもよい. 有効範囲は,そのブロックの終わりまで.

まとめ 独自の型(typedef,列挙型,構造体)を定義することで,変数に持たせる意味がより明確になる. 構造体により,複数のデータからなるオブジェクトを創ることができる. 構造体を対象とする関数を定義するとき,(引数・戻り値の)型は構造体そのものにすべきか,構造体のポインタにすべきか,そのつど検討する.

今後の予定 2007年12月17日(月):第11回授業 2008年1月10日(木):休講 2008年1月17日(木):第2回レポート提出期限 次回授業終了後すぐ,授業Webページにて,第2回レポート課題を掲示します. 2008年1月10日(木):休講 2008年1月17日(木):第2回レポート提出期限 2008年1月21日(月):第12回授業 2008年1月28日(月):第13回授業 2008年1月30日(水):第14回授業