190 likes | 263 Views
今回の課題. 前回の課題の解説 プログラムをより見やすく記述しましょう。 入力部と出力部を, 関数 として宣言します。 関数へデータを渡したり,関数から処理後のデータを受け取る方法を考えましょう。 配列の アドレス を関数とデータをやりとりするための 引数 とします。 本日は,まず, ポインタ の考え方を勉強しましょう。. 前回の課題の解説. プログラム作成時には,何件の入力が行われるか不明ですから,通常,配列の要素数は余裕を持って宣言しておきます。
E N D
今回の課題 • 前回の課題の解説 • プログラムをより見やすく記述しましょう。 • 入力部と出力部を,関数として宣言します。 • 関数へデータを渡したり,関数から処理後のデータを受け取る方法を考えましょう。 • 配列のアドレスを関数とデータをやりとりするための引数とします。 • 本日は,まず,ポインタの考え方を勉強しましょう。
前回の課題の解説 • プログラム作成時には,何件の入力が行われるか不明ですから,通常,配列の要素数は余裕を持って宣言しておきます。 • さてそれでは,実際の入力の際,「入力が終了した。入力のループを終了したい」という処理は,どのように実現すれば良いでしょうか? • 無限ループを設定して,ある条件が満たされたときにループをbreakする,という考え方です。
回答の一例 • homework1.cを確認してください。 • while(1)で無限ループを作っています。 • ループを中断するときは,”N”または”n”を入力します。 • その時点での入力件数が,”i”の中に保存されているので,この値を後ろの処理で利用しています。 • 1文字入力であるにもかかわらずcdを配列で宣言しているのは,文字入力の特殊性にあります。
アドレスとポインタ • 例えば整数型の変数aが int a; と宣言されたとします。このとき,メモリ中に,aのための領域が確保されます。 • メモリ中の「どこに」領域確保されたか,その住所のことを「アドレス」と言います。 • int a; と宣言されたとき,その整数型変数aのアドレスは,&aで表されます。 • scanf(“%d”,&a); の意味を考えてみましょう。
a メモリの中 &の意味 scanf(“%d”, &a);は,「キーボードから入力された十進数値を, 変数aに代入してください」という意味です。 変数aの箱は,メモリ上のどこかにあるはずです。 「56」 変数aの箱 はどこ? メモリの中のどこに変数aがあるかわからない!
56 a メモリの中 &の意味 じゃ,どうすればいい? 「56」 メモリの中の変数aの箱の場所 変数a様 この「住所」が&aの意味 です! OK!
メモリ空間 つまり,scanf(“%d”,&a)ってどんな意味? 部屋番号 (住所) =集合住宅 int a; ↓ アドレス 0003 scanf(“%d”, a); a 0004 0005 アドレス指定! 0006 0007 0008 &a
アドレスとポインタ • 例えば,int *a; と宣言された場合,aのことを「ポインタ」と呼びます。 • ポインタは,メモリのアドレスをポイント(指し示す)働きをします。 • ポインタが指し示しているアドレスに保存されているデータ値は,*a により取り出すことが出来ます。
メモリ空間 & と * は,どう違うの? int a; アドレス int *b; 0002 0003 b=&a; a &a 0004 ← ← 10 5 a=5; 0005 0006 *b=10; *b
演習3 • ensyu3.cを実行し,ポインタの動作を確認しましょう。 • c=&a; を実行せずに,直接 *c=56; を実行しようとするとどうなるでしょう?
配列とポインタ • 例えば,配列 int a[3]; が宣言されたとき,a[0]~a[2]はメモリ上に連続した領域が確保されます。 • 配列名aは,この配列の先頭アドレスを表すポインタの一種です。
メモリ空間 配列変数が宣言された場合 アドレス int a[3]; a int *b; 0002 a[0] ← 10 0003 a[1] b=a; ← 15 0004 a[2] *b=10; 0005 b++; 0006 *b=15; 0007 *b
演習4 • ensyu4.cを実行し,配列要素が連続領域に確保されていることを確認しましょう。 • データ値だけでなく,そのアドレスも出力するようにプログラムを変更しましょう。 • 変数の型をのfloatやdoubleに変更してみましょう。
演習5 • ensyu5.cを実行し,二次元の配列要素が,どのように一次元メモリ領域に確保されていることを確認しましょう。
参考:ポインタと文字列 • 次の二つの文章の働きについて考えてみましょう。 char s[3]=“abc”; char *p=“xyz”; 上は,配列sに文字列abcが代入されます。 下は,メモリ上のどこかにあるxyzという文字列の 先頭アドレスがpに代入れさます。
ポインタと構造体 • 構造体がポインタで示されたとき,そのメンバは,“->”によって参照されます。 struct address friend; struct address *p; p=&friend; p->name=“Hamamoto”; p->tel_no=“042-???”;
そこで住所録プログラムへ • 次回,入力部と出力部を関数として宣言します。 • そのための準備として,「構造体配列の先頭アドレスを取得し,ポインタを一つずつ進めながら配列要素に入力,または配列要素の出力を行う」ようにプログラムを変更しましょう。 • address2.cを参考にして作成してください。
ちょっとした工夫~たくさんのデータ入力~ • homework1.cと同じく,while文を用いて作成してみましょう。 • address2.cをwhile文を用いて書き直したリストがaddress2_2.cです。