情報処理・演習II --- 第3回: ポインタ --情報科学科 井口幸洋 [email protected] 2015/9/30 情報処理・演習II 1 ポインタを学ぶにあたって • ポインタで一番おちこぼれる – 第3回~7回はポインタ ← 5回もやる.重要! • なぜポインタを使うか? – ポインタを使わないとできない計算 – ポインタを使うとコンパクトで効率のよい計算を実現 可能 2015/9/30 情報処理・演習II 2 本日の目標 • メモリとは? • 変数とアドレスの関係について • おまけ: – 家での自習用にCの環境を自分のPCに作ろう 2015/9/30 情報処理・演習II 3 メモリ • メモリに格納するもの – データ – プログラム • メモリには番地がついている(住所と同じ) – 1024個の格納場所があるメモリは0番地~1023番地 まである.これを指定するためには何ビット必要か? 答え: [bits] – 一つの番地には8[bits]格納できる. コンピュータに よってこの値はかわる16[bits], 32[bits], 64[bits]のも ある. 2015/9/30 情報処理・演習II 4 メモリの読み書き CPU(Central Processing Unit) Address Dout Din 10 8 8 Read Write 2015/9/30 Memory Address Din Dout Read Write 情報処理・演習II 5 メモリへの書き込み例(1): 65番地に3を書く CPU(Central Processing Unit) 0001000001 Address 10 00000011 Dout 8 8 Din Read 0 Write 0 最初Write=0にしておく 2015/9/30 情報処理・演習II Memory Address Din Dout Read Write 6 メモリへの書き込み例(2): 65番地に3を書く CPU(Central Processing Unit) 0001000001 Address 10 00000011 Dout 8 8 Din Read 0 Write 1 次に Write=1 にする 2015/9/30 情報処理・演習II Memory Address Din Dout Read Write 7 メモリへの書き込み例(3): 65番地に3を書く CPU(Central Processing Unit) 0001000001 Address 10 00000011 Dout 8 8 Din Read 0 Write 1 次に Write=1 にする 2015/9/30 情報処理・演習II Memory Address Din Dout メモリ内部の 65番地に3が 書き込まれた Read Write 8 メモリからの読み出し例(1): 65番地の内容を読み出す CPU(Central Processing Unit) 0001000001 Address アドレスを セットし, Read = 1 にする. 10 8 Dout 8 Din Read 1 Write 0 2015/9/30 情報処理・演習II Memory Address Din Dout Read Write 9 メモリからの読み出し例(2): 65番地の内容を読み出す CPU(Central Processing Unit) 0001000001 Address 10 8 Dout 8 Din Read 1 Write 0 2015/9/30 情報処理・演習II Memory Address Din 00000011 Dout Read Write 指定された 番地の中身 が読み出さ れ,Doutに 出力. 10 メモリからの読み出し例(3): 65番地の内容を読み出す CPU(Central Processing Unit) 0001000001 Address CPUはDin に入力され た信号を読 みとればよ い. 2015/9/30 10 8 Dout 8 Din Read 1 Write 0 情報処理・演習II Memory Address Din 00000011 Dout Read Write 11 変数とアドレス 例: int x; int y; 仮に変数xを格納する場所が320番地, 変数yを格納する場所が328番地とする. 1番地に8ビット格納可 実際にメモリの何番地に置かれるかは, わからない. OSやコンパイラが決める. 同じプログラムでも実行するたびに違う 場所にあることもある. y x 320 2015/9/30 324 328 情報処理・演習II 332 336 12 注意 • 「変数がどこかのあるアドレスに格納されてい る」 • 「そのアドレスを使って特定の変数を指定でき る」 • 使っている変数がどこのアドレスに格納されたか どうかはプログラムを書く上で意識する必要はな い. 2015/9/30 情報処理・演習II 13 ポインタ • ポインタ(pointer):指し示す?何を? int *p, *q; double *dptr; 中身には 番地を格納 p q dptr int型をさす変数pとqができる(pとqは整数変数を指すポ インタ型変数と呼ぶ. double型をさす変数dptrができる. 2015/9/30 情報処理・演習II 14 アドレス演算子(&の秘密) int *p; int x; 仮定:変数xを格納する場所は320番地. &演算子:その変数のアドレスを取り出す p = &x; x 320 2015/9/30 p 324 328 情報処理・演習II 332 336 15 アドレス演算子(&の秘密) int *p; int x; 仮定:変数xを格納する場所は320番地. &演算子:その変数のアドレスを取り出す p = &x; x p 320 320 2015/9/30 324 328 情報処理・演習II 332 336 16 アドレス演算子(&の秘密) int *p; int x; x=100; scanf("%d", &x); 仮定:変数xを格納する場所は320番地. なぜ、関数scanfの引数にはxのアドレス を渡すのか? x 100 320 2015/9/30 324 328 情報処理・演習II 332 336 17 アドレス演算子(&の秘密) キーボードから値を 読み込みそれを320 番地に格納しておい てくれ! x p 100 320 320 2015/9/30 324 328 情報処理・演習II 332 336 18 アドレス演算子(&の秘密) 了解! キーボードから250 を読み込みましたので ご指定のアドレスに これから入れます。 x 100 320 2015/9/30 324 328 情報処理・演習II 332 336 19 アドレス演算子(&の秘密) Thank you. 入れました。 毎度、ごひいきに ありがとうございました。 x 250 320 2015/9/30 324 328 情報処理・演習II 332 336 20 アドレス演算子(&の秘密) だめな例 scanf("%d", x); これでわかるかなあ? x p 100 320 320 2015/9/30 324 328 情報処理・演習II 332 336 21 アドレス演算子(&の秘密) だめな例 100を渡されたけど、 このおやじわかってんの か? 番地を渡せってんだよ! x p 100 320 320 2015/9/30 324 328 情報処理・演習II 332 336 22 ポインタを通した変数の操作(1) int *p; int x, y; x = 100; p = &x; *p = 5; y = *p + 1; x p y 100 320 2015/9/30 324 328 情報処理・演習II 332 336 23 ポインタを通した変数の操作(2) int *p; int x, y; x = 100; p = &x; *p = 5; y = *p + 1; x p y 320 100 320 2015/9/30 324 328 情報処理・演習II 332 336 24 ポインタを通した変数の操作(2) int *p; int x, y; x = 100; p = &x; *p = 5; y = *p + 1; x *pが式の左側にあるとき: pの中身を読み出して、それを 番地とし、その番地に値を書き こむものとする. p y 320 100 320 2015/9/30 324 328 情報処理・演習II 332 336 25 ポインタを通した変数の操作(3) int *p; int x, y; x = 100; p = &x; *p = 5; y = *p + 1; x *pが式の左側にあるとき: pの中身を読み出して、それを 番地とし、その番地に値を書き こむものとする. この場合、320番地に5を書けと いうことになる. p y 320 5 320 2015/9/30 324 328 情報処理・演習II 332 336 26 ポインタを通した変数の操作(4) int *p; int x, y; x = 100; p = &x; *p = 5; y = *p + 1; x *pが式の右側にあるとき: pの中身をまず読み出して、それを 番地とし、その番地を読み出す. この例では320番地を読み出す. 今回は読み出した値に1を加えてyに 格納. 5 320 2015/9/30 324 y p 6 320 328 情報処理・演習II 332 336 27 ポインタを通した変数の操作(5) 教科書を見ないで中身を埋めなさい x y 19 41 320 324 328 p p = &x; 332 336 p y x *p = *p + 100; 320 324 328 332 336 p y x p = &y; 320 2015/9/30 324 328 332 情報処理・演習II 336 28 ポインタを通した変数の操作(6) 教科書を見ないで中身を埋めなさい p y x *p = *p + 100; 320 2015/9/30 324 328 332 情報処理・演習II 336 29 関数とポインタ • 今までの例←ポインタ?役に立つの? – scanf は一つの例. でも知らなくても使ってたし。。。。 • 今日は本節「関数とポインタ」の所でポインタの 応用を一つだけ学ぶ. 2015/9/30 情報処理・演習II 30 関数とポインタ • 関数呼び出し時の値の受け渡し – 「呼ぶほう」から引数を使って関数に値を渡せる. – 関数の処理がわたったとき「呼んだ方に値を渡すの はreturn文だけ」. 値が一つならいいけど、複数あっ たらどうするの? • ポインタの考え方を使えば複数の値も返せる. 2015/9/30 情報処理・演習II 31 例(関数とポインタ) だめな例 やりたいこと: もらった値を2倍してかえしたい. int main(void) { int a; a = 3; printf(“%d\n”,a); twice(a); printf(“%d\n”,a); return(0); } 2015/9/30 void twice(int x) { x = x * 2; } あれ、メインと関数の変数名 が違うからかなあ? 情報処理・演習II 32 例(関数とポインタ) だめな例 やりたいこと: もらった値を2倍してかえしたい. int main(void) { int a; a = 3; printf(“%d\n”,a); twice(a); printf(“%d\n”,a); return(0); } 2015/9/30 void twice(int a) { a = a * 2; } これでも駄目! なぜ駄目なのか? ヒント: main の変数a, 関数 twice内の変数aは同じ名前だけ で違う場所にある.同姓同名み たい。 情報処理・演習II 33 例(関数とポインタ) 良い例 やりたいこと: もらった値を2倍してかえしたい.番地をわたす! int main(void) { int a; a = 3; printf(“%d\n”,a); twice(&a); printf(“%d\n”,a); return(0); } 2015/9/30 void twice(int *p) { *p = *p * 2; } 関数twiceでは番地をもらいpに いれる. その番地を使ってメイン の変数aが格納されている所を 直接いじってしまう。 情報処理・演習II 34 課題1: ノーヒント • printf を各所にいれて値を追跡せよ. • この時、どうして値がそう変わったか?を図を使っ て説明できるようにしなさい. これができないと定 期試験はできない. 2015/9/30 情報処理・演習II 35 課題2:3倍にするプログラム • 本来はreturnで返すのがよいが、今回はポインタ の勉強のため本節で述べた方法を使ってかきな さい。 • twiceの例をもう1回理解してから、例をみないで 自分で書いてみなさい。 • 変数の箱を書いて図を描いて動作を説明できる ようにしなさい(試験に出るかも). 2015/9/30 情報処理・演習II 36 課題3:値を交換する関数 main では a = 5; b= 3; swap(&a, &b) printf(“a=%d, b=%d\n”,a,b); この動作を完璧に 理解すること! void swap(int *p, int*q) { int tmp; tmp に p が指し示す値を代入; p が指し示すところにqが指し示す値を代入; qが指し示すところにtmpを代入; } 2015/9/30 情報処理・演習II 37 課題4:二つの値を受け取り和と差を返す main では a = 5; b= 3; watosa(&a, &b, &wa, &sa) この動作を完璧に 理解すること! void watosa(int *p, int*q, int *r, int *s) { } 2015/9/30 情報処理・演習II 38 自宅でC言語実行環境を作成する • フリーソフトの学習向けオリジナルC言語コンパ イラ&実行環境「C machine」 を導入 • www.google.co.jp で検索すると出てきます。 2015/9/30 情報処理・演習II 39 ダウンロード 2015/9/30 情報処理・演習II 40 FTPでダウンロードを選択 2015/9/30 情報処理・演習II 41 「保存」を選択 C:にdownloadなどという名前のフォルダを つくっておくとよい. 2015/9/30 情報処理・演習II 42 ファイルを保存 2015/9/30 情報処理・演習II 43 cmkt200.lzhを解凍 • 解凍すると cmkt200 という名のフォルダ内に Cmachine というフォルダができる • このCmachineフォルダを自分の好きなところに 移動しておく。例えばデスクトップに移動してもよ い。 • bin内部のCmachine.exeをダブルクリックすると 開始. プログラムをかいて実行してみてください. 2015/9/30 情報処理・演習II 44 Cmachine実行例 2015/9/30 情報処理・演習II 45
© Copyright 2024 ExpyDoc