ポインタ プログラミング入門2 第10回 芝浦工業大学情報工学科 青木 義満

Slides:



Advertisements
Similar presentations
プログラミング入門2 芝浦工業大学情報工学科青木 義満 第11回構造体. プログラミング入門2 2 構造体 5 人分のサッカー選手データ 全てのデータを関数に渡して,処理する場合 char name[5][256]; int assist[5]; int score[5]; void func( char.
Advertisements

プログラミング演習Ⅱ 第 11 回 ポインタ(2) 情報・知能工学系 山本一公
プログラミング入門2 芝浦工業大学情報工学科青木 義満 第6回関数(2). プログラミング入門2 2 今回の講義内容 関数 配列データの受け渡し ( p.130 ~) 入出力と文字 ( p.198 ~) 文字列の基本 ( p.208 ~)
プログラミング入門2 第1回 イントロダクション 芝浦工業大学情報工学科 青木 義満
プログラミング入門2 第4回 配列 for文 変数宣言 初期化
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
プログラミング入門2 第7回 文字列 数学関数 ファイルの入出力 芝浦工業大学情報工学科 青木 義満
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
プログラミング入門2 ポインタについて補足 構造体 第11回 芝浦工業大学情報工学科 青木 義満、篠埜 功
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
プログラミング入門2 第6回 関数(2) 芝浦工業大学情報工学科 青木 義満
プログラミング演習(2組) 第12回
C言語講座 第4回 ポインタ.
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月10日、H.15(‘03)] 今日のメニュー 1 前回の課題の復習
プログラミング入門2 第12回 データ型 関数のプロトタイプ宣言 動的な記憶域確保 芝浦工業大学情報工学科 青木 義満
プログラミング入門2 第3回 繰り返し文 芝浦工業大学情報工学科 青木 義満
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
構造体 プログラミング入門2 芝浦工業大学情報工学科 青木 義満
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
第10回 プログラミングⅡ 第10回
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
C言語講座 第3回 ポインタ、配列.
プログラミング入門2 第5回 関数(1) 芝浦工業大学情報工学科 青木 義満
プログラミング論 関数ポインタ と 応用(qsort)
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
プログラミング入門2 ファイルの入出力 ポインタ 芝浦工業大学情報工学科 青木 義満
Computer Graphics 第3回 座標変換 芝浦工業大学情報工学科 青木 義満
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
第10章 これはかなり大変な事項!! ~ポインタ~
プログラミング入門2 第8回 ポインタ 情報工学科 篠埜 功.
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
知能情報工学演習I 第9回( C言語第3回) 課題の回答
プログラミング入門2 第11回 情報工学科 篠埜 功.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
講義では、Cプログラミングの基本を学び 演習では、やや実践的なプログラミングを通して学ぶ
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
第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 第12回 データ型 関数のプロトタイプ宣言 動的な記憶域確保 芝浦工業大学情報工学科 青木 義満
プログラミング基礎B 文字列の扱い.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
第2回課題 配布した通り.氏名・学生番号を忘れないこと.
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
精密工学科プログラミング基礎 第7回資料 (11/27実施)
プログラミング入門2 第5回 配列 for文 変数宣言 初期化
知能情報工学演習I 第8回(後半第2回) 課題の回答
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
精密工学科プログラミング基礎Ⅱ 第2回資料 今回の授業で習得してほしいこと: 配列の使い方 (今回は1次元,次回は2次元をやります.)
プログラミング入門2 第5回 配列 変数宣言、初期化について
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
知能情報工学演習I 第11回(後半第5回) 課題の回答
知能情報工学演習I 第9回(後半第3回) 課題の回答
プログラミング演習I 補講用課題
プログラミング 3 ポインタ(1).
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Presentation transcript:

ポインタ プログラミング入門2 第10回 芝浦工業大学情報工学科 青木 義満 I’ll get started with Introduction and Conventional works around our study, then mention our motivation and goal. Next, I’ll explain our 3D Face Modeling Method and its medical application. Finally, I’ll conclude this presentation with some future works. 芝浦工業大学情報工学科 青木 義満

ポインタがオブジェクトを「指す」 int nx; int *pt; pt = &nx; pt   という。 57 int  nx; int  *pt; pt = &nx; nx 1000番地 メモリ上の番地 &nx = 代入 nxのアドレス pt ptにはオブジェクトnxのアドレスが格納されているので,  ptはnxを指している といえる。 プログラミング入門2

ポインタとエイリアス(別名) pt pt int nx; int *pt; nx = 57; pt = &nx; pt は x を指す x ポインタpがオブジェクトxを指すとき,*pはxのエイリアス(別名)となる 重要 プログラミング入門2

今回の講義内容 ポインタと関数 ポインタと配列 プログラミング入門2

ポインタと関数 ソースファイル名:list1004-1.c 関数の引数とポインタ(間違い) Height before : 179 #include <stdio.h> void hiroko(int height) { if ( height < 180) height = 180; } int main(void) int masaki = 179; printf("height before:%d\n", masaki); hiroko(masaki); printf("height after:%d\n", masaki); return (0); 身長を180cmに伸ばしてくれる関数 Height before : 179 Height after : 179 値が変更されていない! プログラミング入門2

値の受け渡し 実引数の値が仮引数の値にコピーされるだけ ・heightには179という値がコピーされる #include <stdio.h> void hiroko(int height) { if ( height < 180) height = 180; } int main(void) int masaki = 179; printf("height before:%d\n", masaki); hiroko(masaki); printf("height after:%d\n", masaki); return (0); ・heightには179という値がコピーされる ・関数内でheightの値は変更されるが,  main文の方のmasakiの値は変更されない! 直接値を変更できない ↓ ポインタを利用して,間接的に変更! プログラミング入門2

ポインタと関数 ソースファイル名:list1004-2.c 関数の引数とポインタ(正解) void hiroko(int *height) #include <stdio.h> void hiroko(int *height) { if ( *height < 180) *height = 180; } int main(void) int masaki = 179; printf("height before:%d\n", masaki); hiroko(&masaki); printf("height after:%d\n", masaki); return (0); 身長を180cmに伸ばしてくれる関数 Height before : 179 Height after : 180 値が変更OK! プログラミング入門2

関数の引数としてのポインタ hiroko(&masaki); void hiroko(int *height) { ポインタを介して,間接的に変数の値を変更 int masaki; masaki = 179; masakiのアドレス(&masaki) を関数に渡す hiroko(&masaki); int *height; height = &masaki; 106番地 masaki height *height *heightはmasakiのエイリアス 180 106番地 179 void hiroko(int *height) { if ( *height < 180) *height = 180; } プログラミング入門2

関数におけるポインタの使用例(p.234) ソースファイル名:list1005-1.c 関数の引数とポインタ(間違い) temp #include <stdio.h> void swap(int nx, int ny) { int temp = nx; nx = ny; ny = temp; } int main(void) int na, nb; puts("二つの整数を入力してください。"); printf("整数A:"); scanf("%d", &na); printf("整数B:"); scanf("%d", &nb); swap(na, nb); puts("これらの値を交換しました。"); printf("整数Aは%dです。\n", na); printf("整数Bは%dです。\n", nb); return (0); temp nxの値を一時的に tempに格納 nyにtemp(元のnxの値) を代入 ny nx    nyの値をnxに代入 変数の値を関数を使って変更したい → ポインタを使いましょう プログラミング入門2

関数におけるポインタの使用例(p.234) ソースファイル名:list1005-2.c 関数の引数とポインタ(正解) #include <stdio.h> void swap(int *nx, int *ny) { int temp = *nx; *nx = *ny; *ny = temp; } int main(void) int na, nb; puts("二つの整数を入力してください。"); printf("整数A:"); scanf("%d", &na); printf("整数B:"); scanf("%d", &nb); swap(&na, &nb); puts("これらの値を交換しました。"); printf("整数Aは%dです。\n", na); printf("整数Bは%dです。\n", nb); return (0); プログラミング入門2

関数とポインタの重要ポイント 関数に対して,変数の値の変更を頼みたい時 関数にその変数へのポインタ(その変数のアドレス)を渡す ポインタ(オブジェクトのアドレス)を渡して, 関数側はそのポインタが指すオブジェクトに対して処理を行う hiroko(&masaki); void hiroko(int *height) プログラミング入門2

関数におけるポインタの使用例(p.236) ソースファイル名:list1007.c 2つの整数の和と差を求める #include <stdio.h> void sum_diff( int n1, int n2, int *sum, int *diff ) { *sum = n1 + n2; *diff = (n1 > n2) ? n1 - n2 : n2 - n1; } int main(void) int na, nb; int wa = 0, sa = 0; puts("二つの整数を入力してください。"); printf("整数A:"); scanf("%d", &na); printf("整数B:"); scanf("%d", &nb); sum_diff( na, nb, &wa, &sa ); printf("和は%dです。\n差は%dです。\n", wa, sa); return (0); 何故,na, nbには&が不要? プログラミング入門2

ポインタを使うか使わないか 値を変更する必要があれば,ポインタで受け渡し そうでなければ,ポインタを使用する必要なし (例えば,その値を計算にしようするだけ などの場合) void sum_diff( int n1, int n2, int *sum, int *diff ) { *sum = n1 + n2; *diff = (n1 > n2) ? n1 - n2 : n2 - n1; } n1, n2 は和と差を求めるために使用するだけ →値だけ使えればよい(ポインタを使う必要なし) sum, diff は変数のアドレスを受け取り,和と差を求めた結果を代入 →値を変更する必要がある(ポインタを使う必要あり) プログラミング入門2

値の並べ替え(ソート,p.237) ソースファイル名: list1008.c 2つの整数値を小さい順に並べる(昇順ソート) #include <stdio.h> /*--- nx・nyが指すオブジェクトの値を交換 ---*/ void swap(int *nx, int *ny) { int temp = *nx; *nx = *ny; *ny = temp; } /*--- *n1≦*n2となるように並べる ---*/ void sort2(int *n1, int *n2) if (*n1 > *n2) swap(n1, n2); int main(void) { int na, nb; puts("二つの整数を入力してください。"); printf("整数A:"); scanf("%d", &na); printf("整数B:"); scanf("%d", &nb); sort2( &na, &nb ); puts("これらの値を昇順に並べました。"); printf("整数Aは%dです。\n", na); printf("整数Bは%dです。\n", nb); return (0); } *n1, *n2, n1, n2には何の値が入っている? プログラミング入門2

scanf関数とポインタ printf関数とscanf関数 printfはただ変数の値を表示するだけ printf(“x = %d\n”, x); scanf(“%d”, &x); printfはただ変数の値を表示するだけ 変数の値を変更する必要なし → そのまま変数を渡す scanfは,キーボードから読み込んだ値を変数に格納する 変数に値を代入(値を変更)する必要 → ポインタ(アドレス)で渡す! プログラミング入門2

ポインタと配列 (p.240) int *ptr = &vc[0]; ソースファイル: list1010.c 配列とポインタ #include <stdio.h> int main(void) { int i; int vc[5] = {10, 20, 30, 40, 50}; int *ptr = &vc[0]; for (i = 0; i < 5; i++) printf("vc[%d] = %d ptr[%d] = %d *(ptr + %d) = %d\n", i, vc[i], i, ptr[i], i, *(ptr + i) ); return (0); } プログラミング入門2

配列とポインタ int *ptr = &vc[0]; ptr + i *(ptr + i) *(ptr + i) = ptr[i] 配列 vc の先頭要素vc[0]のアドレス &vc[0] を   ptrに代入 int *ptr = &vc[0]; vc[0] *ptr ptr[0] ptr + i vc[1] *(ptr+4) *(ptr+3) *(ptr+2) *(ptr+1) ptr[4] ptr[3] ptr[2] ptr[1] vc[2] Ptrが指すオブジェクトのi個後ろの要素 を指すポインタ vc[3] vc[4] *(ptr + i) ptr Ptrが指すオブジェクトのi個後ろの要素 のエイリアス *(ptr + i) = ptr[i] ポインタに対して [ ]を適用すること で,配列のように扱える!! プログラミング入門2

配列とアドレス (p.242) 添え字演算子[ ]を使わずに単独に現れた配列名は, その配列の先頭要素へのポインタとみなされる ソースファイル: list1011.c 配列のアドレスを表示 #include <stdio.h> int main(void) { int vc[3]; printf("vc :%p\n", vc); printf("vc[0]のアドレス:%p\n", &vc[0]); printf("vc[1]のアドレス:%p\n", &vc[1]); printf("vc[2]のアドレス:%p\n", &vc[2]); return (0); } 添え字演算子[ ]を使わずに単独に現れた配列名は, その配列の先頭要素へのポインタとみなされる プログラミング入門2

配列の受け渡し (p.244) ソースファイル名:list1013.c 関数への配列の受け渡し(復習) #include <stdio.h> void int_set( int vc[ ] ) { int i; for (i = 0; i < 5; i++) vc[i] = 0; } int main(void) int i; int ary[ ] = {1, 2, 3, 4, 5}; int_set( ary ); printf("ary[%d] = %d\n", i, ary[i]); return (0); int *vc 復習 関数で配列を受け取る時, int vc[ ] → int型のオブジェクトのアドレスを受け取る  = int *vc で受け取り可能! 配列名(ary) =配列の先頭要素のアドレス =&(ary[0]) int型のオブジェクトのアドレスを渡す プログラミング入門2

配列の受け渡し 関数間での配列の受け渡し 先頭要素へのポインタで行う 受け取り側の関数は,そのポインタに対して添え字演算子 [ ]を適用することで,配列のようにアクセスできる int_set( ary ); void int_set( int *vc ) &ary[0] (500番地) int型オブジェクトのアドレスを受け取るので, ポインタ(int *)で宣言 500番地 ary[0] *vc vc[0] 502番地 ary[1] *(vc+4) *(vc+3) *(vc+2) *(vc+1) vc[4] vc[3] vc[2] vc[1] 504番地 ary[2] 506番地 ary[3] 508番地 ary[4] vc プログラミング入門2

scanf関数とポインタ scanfは,キーボードから読み込んだ値を変数に格納する 文字列の場合 変数に値を代入(値を変更)する必要 → ポインタ(アドレス)で渡す! 文字列の場合 文字配列の先頭アドレスを渡してやればよい &をつけずに,配列名でOK char name[256]; scanf( “%s”, name ); name = &(name[0]) プログラミング入門2

二次元配列の関数への渡し方 ソースファイル名: 2jigen.c 関数への二次元配列データの受け渡し 先頭の要素数は省略可能 #include <stdio.h> void print_name( char x[ ][256] ) { int i; for(i=0; i < 4; i++){ printf("name[%d] = %s\n", i, x[i] ); } int main(void) char name[4][256]={"aoki", "morishima", "tokunaga", "yanagisawa" }; print_name( name ); return(0); 先頭の要素数は省略可能 配列名で関数へ受け渡し プログラミング入門2

演習課題 BMI 25以上 → 肥満 BMI 18.5以上25未満 → 標準体重 BMI 18.5未満 → 低体重 ファイル名:kadai10-1.c ポインタと関数,配列 3名分の氏名,身長,体重データが格納されている配列を受け取って,肥満度(BMI値)を計算し,全員の肥満度を表示する関数を設計せよ 氏名、身長、体重、BMI値を格納する配列はMain関数で宣言、関数にそれらのデータを渡して関数内でBMI値を計算して配列BMIに結果を格納。 Main関数中でBMI値に基づき、判定結果を表示。 氏名,身長,体重のデータはキーボード読込み,ファイル読込みのどちらでも良い。 void calculate_bmi( char name[ ][256], double *height, double *weight, double *bmi ) 名前の配列 身長の配列 体重の配列 BMIの配列 <BMI(Body mass index)の計算方法> 身長の二乗に対する体重の比で体格を表す指数 BMI=体重(kg)/(身長m)2 BMI 25以上 → 肥満 BMI 18.5以上25未満  → 標準体重 BMI 18.5未満 → 低体重 プログラミング入門2

演習課題 ファイル名:kadai10-2.c void select_sort( int *vc, int no ) 要素数noのint型配列データを受け取り,値の小さい順に要素を並べ替える(ソート)関数を設計し, その動作を確認せよ。なお,並べ替えのアルゴリズムは以下の手順に従うこと。(他のアルゴリズムでも良い) void select_sort( int *vc, int no ) セレクトソート法(最も単純なソート法) ※3, 5, 2, 4, 1 というデータを例に説明 A.まず、データ全体の中から、最小の値を探す 3, 5, 2, 4, 1 B.探し出した最小の値と、データの先頭の値を、入れ替える 1, 5, 2, 4, 3 C.次に、先頭から2番目より最後までの値の中から、最小の値を探す 1, 5, 2, 4, 3 D.探し出した最小の値と、先頭から2番目の値の値を、入れ替える 1, 2, 5, 4, 3 E.同様に、先頭から3番目より最後までの値の中から、最小の値を探す 1, 2, 5, 4, 3 F.探し出した最小の値と、先頭から3番目の値の値を、入れ替える 1, 2, 3, 4, 5 G.最後まで処理を繰り返す この結果、順番が1, 2, 3, 4, 5 と並び替えられる 提出期限: 12月17日(月)13:00(厳守) 提出先: yaoki@sic.shibaura-it.ac.jp メールのタイトル:pro2-10 学籍番号+自分の苗字 例) pro2-10 L02001 aoki プログラミング入門2