第10章 これはかなり大変な事項!! ~ポインタ~ メモリ上の番地アドレスから遡って、変数の値 を見ていったりするする 第10章 ポインタ
前回やったこと 文字を変数に入れるための char 型 文字列は配列を使い、その最後には『\0』が終 了点として必ず付けられる コンピュータ内で文字と整数値は対応しており、 それは文字コードに則って決められている 第10章 ポインタ
今日の予定 アドレスとポインタ 変数のアドレスとポインタ変数 ポインタと関数 ポインタと配列 第10章 ポインタ
アドレスとポインタ(1) すべての変数は、メモリ上にその分の領域とい うものが確保されている そのメモリ上の位置、番地のことをアドレスと いう ある変数のアドレスは、その変数名に『&』を 付け加えたもので、たとえば、変数a のアドレ スは『&a』と表される 第10章 ポインタ
アドレスとポインタ(2) このアドレスを代入できる特殊な変数をポイン タという 宣言 初期化 int *p; 代入時は『*』がいらないので注意 int *p; p = &a; 第10章 ポインタ
アドレスとポインタ(3) また以下のようにポインタ変数に『*』をつけ ると、ポインタに入っているアドレスの指す変 数と同じ扱いになる つまり *p = a int a = 25; int *p; p = &a; *p = 50; printf(“%d\n”, a); 色々省略 宣言時の『*』とは別個に 思って 第10章 ポインタ
アドレスとポインタ(4) ここでひとつ実行してみよう #include <stdio.h> int main(){ int a = 25; int *p = &a; printf(“%d\n”, a); printf(“%d\n”, *p); *p = 50; return 0; } 第10章 ポインタ
アドレスとポインタ 実行結果 このように『*p』など『*』などをつけてアド レス先の変数と同じ扱いになることを 間接参照というよ 間接参照というよ 用語は好きに覚えてね 第10章 ポインタ
練習問題1 以下のコードを必ず使って、入力した数値を間 接参照で表示し、値を10倍して今度は元の変数 で表示をやってみよう 実行例はこちら printf(“a > %d\n”, *p); printf(“a × 10 = %d\n”, num); 第10章 ポインタ
練習問題1 回答例 ちょっと まわりく どいかな #include <stdio.h> int main(){ int num; int *p; printf("値を入力してください > "); scanf("%d", &num); p = # printf("num > %d\n", *p); *p *= 10; printf("num × 10 = %d\n", num); return 0; } 第10章 ポインタ
ポインタと関数(1) 以下のプログラムは sub 関数で変数a の値を変 更しているが、うまくいっていない #include <stdio.h> void sub(int a){ a = 100; } int main(){ int a = 0; sub(a); printf(“%d\n”, a); return 0; 第10章 ポインタ
ポインタと関数(2) 関数に渡した値は、関数内の変数にコピーされ、 使用されている つまりその変数はローカル変数(そういやそんな のあった)なので、値を変更しても、関数の外ま でそれが適用されない ゆえに、前ページのプログラムの値は変わらな い 第10章 ポインタ
ポインタと関数(3) 今度は関数にアドレスを渡してみる #include <stdio.h> void sub(int *p){ } int main(){ int a = 0; sub(&a); printf(“%d\n”, a); return 0; 第10章 ポインタ
ポインタと関数(4) ポインタに『*』をつけたものは、そのアドレ スが指す変数と同じに扱う(2度目) この場合、アドレスを経由して変数の値をい じったため、関数の外においても変更が適用さ れているよ 第10章 ポインタ
練習問題2 半径を入力して、そこから円の円周と面積を求 める calc 関数を作ってみよう その時必ず以下の main 関数を用いてね int main(){ double a, b, c; printf(“半径は > ”); scanf(“%lf”, &a); calc(a, &b, &c); printf(“円周は > %f\n”, b); printf(“面積は > %f\n”, c); return 0; } 円周率は 3.14 で 第10章 ポインタ
練習問題2 回答例 『*』ば かりで すね #include <stdio.h> void calc(double a,double *b, double *c){ *b = a * 2 * 3.14; *c = a * a * 3.14; } int main(){ double a, b, c; printf(“半径は > ”); scanf("%lf", &a); calc(a,&b,&c); printf("円周は > %f\n",b); printf("面積は > %f\n",c); return 0; 第10章 ポインタ
ポインタと配列(1) 配列のアドレス int num[5]; &num[0], &num[1], &num[2], ……… たとえば という配列をつくったとして、それぞれの変数のアドレ スは &num[0], &num[1], &num[2], ……… となるのはイメージしやすいと思うけど、実は配列名で ある num も &num[0] と同じく num[0] のアドレス を表している int num[5]; 第10章 ポインタ
ポインタと配列(2) 配列名 num が &num[0] と表すとき、 num+1 は &num[1]、num+2 は &num[2]… を表すことになる つまり ⇒ ちなみに『*p』も『*(p+1)』『*(p+2)』…と していくことで、隣の領域にある変数の値を示 していくことができる *num == num[0] *(num+1) == num[1] *(num+2) == num[2] 第10章 ポインタ
ポインタと配列(3) これで関数に配列を渡すやり方が説明できる! 実行してみよう! #include <stdio.h> void clear(int *p){ for(int i=0; i < 5; i++){ *(p + i) = 0; } int main(){ int num[5] = {98, 102, 5, 77, 236}; clear(num); printf(“%d\n”, num[i]); } return 0; 実行してみよう! 第10章 ポインタ
ポインタと配列(4) 実行結果 clear 関数に配列名 num を引数として渡し、そ れをポインタで受け取る 関数内の処理で『*p』『*(p+1)』『*(p+2)』 …としていくことで『*num[0]』 『*num[1]』『*num[2]』…と同じことをし ているよ 第10章 ポインタ
ポインタのまとめ 変数のアドレスを格納できるポインタ変数 ポインタに『*』をつけることでアドレス先の 変数と同じ扱いができる 配列名は配列の先頭の変数のアドレスと同じ 配列を関数に渡す時、ポインタとして受けるこ とができる ややこしいのでまとめてみました 第10章 ポインタ
練習問題3 文字列を入力させて、その長さを算出する strlen 関数を使ったプログラムを作ってみよう ヒント:文字列は『\0』 で必ず終わるよ 文字列を入力させて、その長さを算出する strlen 関数を使ったプログラムを作ってみよう int main(){ char words[128]; int num = 0; printf("文字列を入力してみよう > "); scanf("%s", words); num = strlen(words); printf("文字列の長さは %d です\n", num); return 0; } main 関数はこんなカンジ 第10章 ポインタ
練習問題3 回答例 #include <stdio.h> int strlen(char *p){ int n = 0; while(*p != '\0'){ p++; // このカタチでもポインタをずらせる n++; } return n; int main(){ char words[128]; // ちゃんと十分に配列を確保しよう! int num = 0; printf(“文字列を入力してみよう > ”); scanf("%s", words); num = strlen(words); printf("文字列の長さは %d です\n", num); return 0; 第10章 ポインタ
次回予告 変数をまとめて宣言する方法 ヘッダーファイルを自分で作る プログラミングで便利な構造体のはなし 第10章 ポインタ
テンプレ テンプレ 第10章 ポインタ