Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


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

1 ポインタ プログラミング入門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. 芝浦工業大学情報工学科 青木 義満

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

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

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

5 ポインタと関数 ソースファイル名: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

6 値の受け渡し 実引数の値が仮引数の値にコピーされるだけ ・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

7 ポインタと関数 ソースファイル名: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

8 関数の引数としてのポインタ 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

9 関数におけるポインタの使用例(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

10 関数におけるポインタの使用例(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

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

12 関数におけるポインタの使用例(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

13 ポインタを使うか使わないか 値を変更する必要があれば,ポインタで受け渡し そうでなければ,ポインタを使用する必要なし
(例えば,その値を計算にしようするだけ などの場合) 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

14 値の並べ替え(ソート,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

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

16 ポインタと配列 (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

17 配列とポインタ 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

18 配列とアドレス (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

19 配列の受け渡し (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

20 配列の受け渡し 関数間での配列の受け渡し 先頭要素へのポインタで行う
受け取り側の関数は,そのポインタに対して添え字演算子 [ ]を適用することで,配列のようにアクセスできる 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

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

22 二次元配列の関数への渡し方 ソースファイル名: 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

23 演習課題 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

24 演習課題 ファイル名: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(厳守) メールのタイトル:pro2-10 学籍番号+自分の苗字 例) pro2-10 L aoki プログラミング入門2


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

Similar presentations


Ads by Google