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