プログラミング及び演習 第1回 講義概容・実行制御

Similar documents
プログラミング及び演習 第1回 講義概容・実行制御

プログラミング及び演習 第1回 講義概容・実行制御

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

プログラミング及び演習 第1回 講義概容・実行制御

演算増幅器

Taro-リストⅠ(公開版).jtd

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

Prog1_15th

Microsoft Word - no206.docx

プログラミングI第10回

Microsoft PowerPoint - lec10.ppt

PowerPoint プレゼンテーション

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

memo

Microsoft PowerPoint - CproNt02.ppt [互換モード]

Microsoft PowerPoint - 13th.ppt [互換モード]

Microsoft PowerPoint - kougi11.ppt

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Taro-ポインタ変数Ⅰ(公開版).j

PowerPoint プレゼンテーション

講習No.12

tuat1.dvi

program7app.ppt

memo

Microsoft Word - Cプログラミング演習(7)

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

Microsoft Word - Cプログラミング演習(12)

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

Microsoft PowerPoint - handout07.ppt [互換モード]

プログラミング基礎

Microsoft Word - 3new.doc

PowerPoint プレゼンテーション

Microsoft Word - C.....u.K...doc

Taro-リストⅢ(公開版).jtd

PowerPoint Template

02: 変数と標準入出力

memo

02: 変数と標準入出力

Microsoft PowerPoint - 12.ppt [互換モード]

Microsoft PowerPoint - 計算機言語 第7回.ppt

Microsoft Word - no15.docx

PowerPoint プレゼンテーション

gengo1-11

Microsoft PowerPoint - 13.ppt [互換モード]

PowerPoint プレゼンテーション

kiso2-09.key

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

プログラミング基礎

Microsoft PowerPoint ppt

Taro-スタック(公開版).jtd

II 3 yacc (2) 2005 : Yacc 0 ~nakai/ipp2 1 C main main 1 NULL NULL for 2 (a) Yacc 2 (b) 2 3 y

Microsoft Word - Cプログラミング演習(10)

Cプログラミング1(再) 第2回

Microsoft PowerPoint - 12.ppt [互換モード]

Microsoft PowerPoint - kougi9.ppt

2006年10月5日(木)実施

Prog1_12th

gengo1-2

‚æ4›ñ

02: 変数と標準入出力

memo

JavaプログラミングⅠ

Microsoft PowerPoint - 11.pptx

1. 入力した正の整数を降順に並べ換えて出力するプログラムを作成せよ プログラムは個別にコンパイルし make コマンドで実行すること 入力データは 50 以下とし 以下の数が混在しているとする 16 進数 : 先頭 1 文字が x または X( エックスの小文字か大文字 ) 8 進数 : 先頭 1

PowerPoint プレゼンテーション

Microsoft Word - no12.doc

Prog1_6th

Microsoft PowerPoint - 09.pptx

Microsoft Word - 13

Microsoft PowerPoint pptx

Microsoft PowerPoint - kougi10.ppt

PowerPoint Presentation

Microsoft Word - Cプログラミング演習(8)

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

untitled

memo

配列, 関数, 構造体

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

memo

PowerPoint Presentation

Taro-2分探索木Ⅱ(公開版).jtd

slide5.pptx

Microsoft PowerPoint - kougi8.ppt

Prog1_10th

プログラミング実習I

memo

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

始めに, 最下位共通先祖を求めるための関数 LcaDFS( int v ) の処理を記述する. この関数は値を返さない再帰的な void 関数で, 点 v を根とする木 T の部分木を深さ優先探索する. 整数の引数 v は, 木 T の点を示す点番号で, 配列 NodeSpace[ ] へのカーソル

Microsoft Word - no205.docx

Taro-再帰関数Ⅱ(公開版).jtd

PowerPoint プレゼンテーション - 物理学情報処理演習

PowerPoint プレゼンテーション

Microsoft Word - 03

第 2 章インタフェース定義言語 (IDL) IDL とは 言語や OS に依存しないインタフェース定義を行うためのインタフェース定義言語です CORBA アプリケーションを作成する場合は インタフェースを定義した IDL ファイルを作成する必要があります ここでは IDL の文法や IDL ファイ

PowerPoint プレゼンテーション

Taro-ファイル処理(公開版).jtd

概要 プログラミング論 変数のスコープ, 記憶クラス. メモリ動的確保. 変数のスコープ 重要. おそらく簡単. 記憶クラス 自動変数 (auto) と静的変数 (static). スコープほどではないが重要.

PowerPoint プレゼンテーション

Transcription:

プログラミング及び演習 第 9 回列挙型 構造体 ( 教科書第 11 章 ) (2014/06/14) 講義担当 情報連携統括本部情報戦略室 森健策

本日の講義 演習の内容 列挙型 / 構造体 第 11 章 講義 演習ホームページ http://www.newves.org/~mori/14programming ところで,. だんだん難しくなってきました ポインタは2 回目で理解できましたか?

列挙型 名前つき整数定数のリスト 定義方法 enum タグ名 { 列挙リスト ; enum color_type {red, green, yellow; 使用時の宣言 enum タグ名変数名 ; enum color_type mycolor; 定義と宣言を同時 enum color_type {red, green, yellow mycolor; 列挙型の定数に整数が代入される リストの最初が 0, 後は順に加算 強制的に値を与えることも可能 enum color_type {red, green=9, yellow mycolor; (yellow は 10)

回答 なぜ列挙型? 自己説明的なプログラムを記述するため プログラム例 #include <stdio.h> enum computer {keyboard, CPU, screen, printer; int main() { enum computer comp; comp = CPU; printf("%d 0", comp); 次のページ 信号の状態を列挙型で表している 整数値で表すことも可能だが列挙型を使えばどんな状態を考えてプログラムが記述されているのか明確

#include <stdio.h> enum state {RED, YELLOW, GREEN; int main() { enum state s; s = RED; while(1){ if(s==red) printf("red %d n", s); if(s==yellow) printf("yellow %d n", s); if(s==green) printf("green %d n", s); sleep(3); switch(s){ case RED: printf("change from RED to GREEN n" ); s = GREEN; break; case YELLOW: printf("change from YELLOW to RED n" ); s = RED; break; case GREEN: printf("change from GREEN to YELLOW n" ); s = YELLOW; break; default: break;

構造体 構造体とは 異なるデータを一つのグループとして取り扱う方法 例電話帳 char 型 名前 char 型 電話番号 char 型 メールアドレス int 型 累積通話時間 int 型 通し番号 例日付 char 型 年号 int 型 年 int 型 月 int 型 日

構造体型 構造体変数の宣言 構造体型の宣言 struct date{ char era[10]; int year; int month; int day; ; "date" は構造体型のタグ era, year, month, date は構造体型のメンバ 構造体型変数の宣言 struct date a; 構造体 date 型 (struct date 型 ) の a という変数 これで複数の変数をまとめて取り扱える変数が完成

各メンバにアクセスするには "." を利用する struct date{ char era[10]; int year; int month; int day; ; struct date a; の場合 a.era[i] で era 配列にアクセス a.year で year にアクセス a.month で month にアクセス a.day で day にアクセス char era[10] year month day 構造体型変数 a

構造体変数のコピー 初期化 構造体変数のコピー struct date a, e; と宣言されている場合 e=a; でaの内容をeにコピー可能 構造体変数の初期化 struct date a={"heisei", 4,5,6; で初期化可能

構造体型と構造体変数の同時宣言 以下のように宣言可能 struct date{ char era[10]; int year; int month; int day; a; struct person{ char name[40]; struct{char adr[90]; char phone[16]; home; struct{char adr[90]; char phone[16]; office; x; アクセスは x.home.adr, x.name, x.office.adr などとする

構造体サンプルプログラム #include <stdio.h> struct date{ char era[10]; int year; 大域変数宣言ではないことに注意 int month; int day; ; main() { struct date a,e; strcpy(a.era, "Meiji"); a.year = 40; a.month = 5; a.day = 10; e=a; printf( "%s %d Nen %d Gatsu %d Nichi n", a.era, a.year, a.month, a.day); printf( "%s %d Nen %d Gatsu %d Nichi n", e.era, e.year, e.month, e.day);

構造体へのポインタ 構造体変数に対するポインタも作成可能 例 struct date a, *p; p は struct date 型へのポインタ変数 p = &a; とすれば構造体型変数 a へのポインタが p に代入される ポインタ変数時のアクセス方法 (*p).year もしくは p->year

構造体を関数とやりとりする 方法は 2 つ 値呼び出し (call by value) 関数呼び出し時に構造体引数の内容が複写される 参照呼出し (call by reference) 関数呼び出し時に構造体へのポインタを渡す 構造体が大きな場合 ( メンバに大きな配列が含まれている場合 ) に構造体自身の複写をしなくてもよいので高速

値呼び出しの例 #include <stdio.h> struct date{ char era[10]; int year; int month; int day; ; void writedate(struct date a){ printf( "%s %d Nen %d Gatsu %d Nichi n", a.era, a.year, a.month, a.day); struct date readdate() { struct date d; scanf( "%s %d %d %d", d.era, &(d.year), &(d.month), &(d.day)); return d; main() { struct date d; d=readdate(); writedate(d);

正しく動かない例 何故? #include <stdio.h> struct date{ char era[10]; int year; int month; int day; ; void writedate(struct date a){ printf( "%s %d Nen %d Gatsu %d Nichi n", a.era, a.year, a.month, a.day); void readdate(struct date d) { scanf( "%s %d %d %d", d.era, &(d.year), &(d.month), &(d.day)); main() { struct date d; readdate(d); writedate(d);

参照呼出しの例 #include <stdio.h> struct date{ char era[10]; int year; int month; int day; ; void writedate(struct date *a){ printf( "%s %d Nen %d Gatsu %d Nichi n", a->era, a->year, a->month, a->day); void readdate(struct date *d) { scanf( "%s %d %d %d", d->era, &(d->year), &(d->month), &(d->day)); main() { struct date d; readdate(&d); writedate(&d);

構造体実践使用例表の作成 住所検索プログラム 方針 1 人の住所情報 ( 氏名, 郵便番号, 住所等 ) は構造体 person に格納 構造体 person の配列を作成することで多数人の住所を管理

構造体の配列 構造体 person struct person{ char name[40]; char address[80]; char phone[12]; ; struct person table[100]; 100 人分のデータを格納する table を作成 アクセス方法 table[i].name, table[i].address, table[i].phone

#include <stdio.h> #define TABLESIZE 100 struct person{ 住所録検索プログラム char name[40]; char address[80]; char phone[12]; ; void quit(char *message) { fputs(message,stdout); exit(1); int main(int argc, char **argv) { struct person table[tablesize]; FILE *in; char target[40]; int num; int i,j; if((in=fopen(argv[1],"r"))==null){ quit( "File Not Found"); for(num=0;num<tablesize;num++){ if(fscanf(in,"%s %s %s", table[num].name,table[num].address,table[num].phone )==EOF) break;

while(1){ printf("input name:"); fgets(target,40,stdin); j=0; while(j<40){ if(target[j]==' n') target[j]=' 0'; j++; if(target[0]==' 0') return 0; for(i=0; i<num; i++){ if(strcmp(table[i].name,target)==0){ printf( "Address %s Phone %s n", table[i].address, table[i].phone); break; if(i==num) printf("unknow person");

新しいデータ型を定義する 既存の型 プログラマが新しく定義した型に自由に名称をつけることが可能 typedef を用いる 定義の例 typedef int Seisuu32; typedef unsigned short weight; typedef int lengthtable[10]; typedef struct { int x; int y; Coord2D;

typedef の例 定義の例 typedef int Seisuu32; typedef unsigned short weight; typedef int lengthtable[10]; typedef struct { int x; int y; Coord2D; 使用例 Seisuu32 a; weight b; lengthtable b; Coord2D a; メリット プログラム自体が説明的になる typedef 宣言のみを書き換えれば型変更が可能

関数ポインタにおける typedef typedef int functype(int); functype は int 型引数を持ち,int 型を変数を返す関数の型 typedef functype *funcptrtype; functypeptr は functype 型の関数へのポインタ型 funcptrtype functable[10]; functable は関数へのポインタの配列

列挙型と typedef 独自名の列挙型を作成可能 typedef enum{red, GREEN, BLUE SignalStatus; SignalStatus signal_1; SignalStatus signal_2;

共用体 同じメモリ領域を複数の変数で共有するもの メモリを共有する変数の型が同じである必要は無い 複数の変数を同時に使用することは不可能 同じメモリ領域を共有しているため 定義自体は構造体と類似 アクセス方法は構造体と同様 ドット演算子 アロー演算子

共用体の宣言 union がキーワード union u_type{ int i; char c[2]; double d; sample; d c[0] c[1] i 共有されるメモリ領域

#include <stdio.h> typedef enum {inttype, floattype Type; typedef union{ int intnum; float floatnum; Value; typedef struct{ Type type; Value value; Number; void numprint(number x) { switch(x.type){ case inttype: printf("%d n",x.value.intnum); break; case floattype: printf("%f n",x.value.floatnum); break; default: fprintf(stderr, "Unknown Type n"); exit(1); 共用体の使用 main() { Number a; a.type=floattype; a.value.floatnum = 10.67; numprint(a); a.type=inttype; a.value.intnum = 2; numprint(a); a.type=floattype; numprint(a);

共用体を用いたバイト順入れ替え #include <stdio.h> typedef union{ int i; unsigned char c[4]; SwabUnion; void swabint(swabunion *u) { unsigned char tmp[4]; tmp[3]=u->c[0]; tmp[2]=u->c[1]; tmp[1]=u->c[2]; tmp[0]=u->c[3]; u->c[0]=tmp[0]; u->c[1]=tmp[1]; u->c[2]=tmp[2]; u->c[3]=tmp[3]; main() { SwabUnion swabunion; swabunion.i=132430; printf( "%d(%x) n",swabunion.i, swabunion.i); swabint(&swabunion); printf( "%d(%x) n",swabunion.i, swabunion.i);

以降来週の内容 ( 予定 )

自己参照構造体 (K&R p.169) 構造体内部に同じ構造体へポインタが定義されている 構造体自身を構造体メンバとして定義するのではなく 構造体へのポインタが定義される 例 struct tnode{ char *word; int count; struct tnode *left; struct tnode *right;

相互参照構造体 異なる構造体がお互いの構造体へのポインタを持つ 実体を宣言するのではなくポインタとして宣言するのがポイント 例 struct t { int a; int b; struct s *st_s; ; struct s { int c; int d; struct t *st_t; それぞれでそれぞれの実体を宣言してしまうと "chicken-egg" 問題となってしまう

自己参照構造体の使用例 2 分木リスト 例 入力されるテキストの出現頻度をカウント 単語毎に 1 つのノードを持つ 単語テキストへのポインタ 出現回数のポインタ 右の子ノードへのポインタ 左の子ノードへのポインタ 任意のノード 左の部分木 : 辞書順で小さい単語 右の部分木 : 辞書順で大きな単語

2 分木の構築 入力テキスト "now is the time for all good men to come to the aid of their party" 構築される 2 分木 now is the for men of time all good party their to aid come

新たな単語か否かのチェック ルートから出発 ノードに格納されている単語と入力単語をチェック 2 つが一致したら 既出 入力単語がノードの単語よりも 小さければ左の子供に対して探索を続行 大きければ右の子供に対して探索を続行 求める方向に子供がなければ 新たな単語 新たな単語 を 2 分木に追加

ノードを構造体で定義 struct tnode{ char *word; int count; struct tnode *left; struct tnode *right; ツリー構造表現は自己参照構造体の使用の典型例

lec9-wordsearch.c (1/5) #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #define MAXWORD 100 struct tnode { char *word; int count; struct tnode *left; struct tnode *right; ; struct tnode *addtree(struct tnode *, char *); struct tnode *talloc(void); void treeprint(struct tnode *); int getword(char *, int); int getch(void); void ungetch(int c);

lec9-wordsearch.c (2/5) int main(int argc, char **argv) { struct tnode *root; char word[maxword]; root = NULL; while(getword(word,maxword)!=eof){ if(isalpha(word[0])){ root = addtree(root,word); treeprint(root); return(0);

lec9-wordsearch.c (3/5) struct tnode* addtree(struct tnode *p, char *w) { int cond; if(p==null){ p = talloc(); p->word = strdup(w); p->count = 1; p->left = p->right = NULL; else if ((cond=strcmp(w,p->word))==0){ p->count++; else if(cond<0){ p->left = addtree(p->left,w); else{ p->right = addtree(p->right,w); return p;

lec9-wordsearch.c (4/5) void treeprint(struct tnode *p) { if(p!=null){ treeprint(p->left); printf("%4d %s n", p->count, p->word); treeprint(p->right); struct tnode *talloc(void) { return((struct tnode *)malloc(sizeof(struct tnode)));

lec9-wordsearch.c (5/5) int getword(char *word, int lim) { int c; char *w = word; while(isspace(c=getch())) ; if(c!=eof) *w++=c; if(!isalpha(c)){ *w = ' 0'; return c; for( ; --lim>0; w++){ if(!isalnum(*w=getch())){ ungetch(*w); break; *w = ' 0'; return word[0];