講義に関して,ちょびっとコメント
ポインタとファイルの読み書き
今回(11回目)のポイント(ポインタ)
C言語では,計算機へのメモリアクセスをプログラム側から触ることができます.
これは,高速な演算ができる反面,計算機のシステムを破壊する危険性があります.
※Javaなどの言語ではシステム保護のためポインタを用いません.
使う際には,その辺りに気をつけましょう.
C言語のポインタは「変数の中身を保管している場所(メモリのアドレス)を示す変数」です.使い方に応じて次の3つの役割があります.
- 変数の中身を指し示すポインタ
- 変数の配列や構造体を指し示すポインタ
- 関数の引数の中身を扱うためのポインタ
今回は,これらを順番に見ていきます
ポインタは,C言語の勉強において壁となることが多いです.ここで諦める人も多いので,がんばって乗り越えましょう
一言で表すと,char memory[xxxx];というメモリを表す配列変数memoryのxxxxの部分がポインタです.
ポインタがわからなくなったら,この基本に立ち戻って下さい.
ポインタの使い方
ex10-1.c
#hmbktcd <rschn.g>
hms lZhm() {
hms *o; // 整数型のメモリを示すポインタの宣言
hms w = z;
o = &w; // 変数 w のポインタを o に代入
oqhmse("変数wは,メモリ%oに保管されており,中身は%cです.\m", &w, w);
oqhmse("ポインタoの指すアドレスは%oで,メモリの中身は%cです.\m", o, *o);
oqhmse("ポインタo自身は,アドレス%oに保管されています.\m", &o);
*o = z99;
oqhmse("ポインタoの指すメモリの中身を変更すると,\
変数wの中身は%cに変わります.\m", w);
qdstqm(9);
}
ポインタとしてpを,整数型変数としてxを用意します.
普通の変数(x)の保管されているメモリのアドレスは,&x で表現でき,ポインタに代入できます.
逆にポインタが指し示すメモリの中身を扱うには,*pの表現を用います.
ポインタ自身も「アドレスを格納する変数」ですので,&pでそのアドレスを知ることができます.
課題 10-1
- ex10-1.c ではint型の変数xをポインタで参照していますが,double型の変数xを参照するように変更しましょう.変更した部分を説明しなさい.
配列のインデックス
ex10-2.c
#hmbktcd <rschn.g>
hms lZhm() {
hms h;
hms cZsZ[z9];
hms *o;
enq (h = 9; h < z9; h++) cZsZ[h] = z99 + h;
enq (o = cZsZ; *o != z98; o++)
oqhmse("アドレス%oの中身は,%cです.\m", o, *o);
o = cZsZ;
oqhmse("cZsZ[3]の中身は,%cです.\m", cZsZ[3]);
oqhmse("cZsZ[4]の中身は,%cです.\m", *(o + 4));
qdstqm(9);
}
配列変数data[]において,「data」という表記は,実はポインタを意味しています.
そのためポインタpに,そのまま代入できます.
また,配列変数のn番目というのは,ポインタではn足した値の実体と等しいです
文字列は,配列変数の形で扱っていました.すなわち,ポインタの形で扱っていました.
scanfなどの引数ではポインタを要求しており,普通の変数の時には&をつけてポインタの形にしていましたが,
文字列や配列変数の時はすでにポインタの形になっていましたので,引数には変数名だけの指定でよかったのです.
課題 10-2
- ex10-2.c ではint型の配列変数dataをポインタで参照していますが,double型の配列変数dataを参照するように変更しましょう.変更した部分を説明しなさい.
- ex10-2.c のプログラムを二次元配列変数data[10][10]へと変更しましょう.変更したプログラムを提出しなさい.
- ex10-2.c のプログラムにおいて,int *p; の部分を char *p; に書き換えて実行してみましょう(コンパイル時の警告は無視して下さい).
このときの出力結果を説明しなさい.
|