C 言語講座 第 7 回 ポインター
メモリとアドレス(ポインターの前 に) コンピュータのメモリには 1 バイトずつ 0 番地、 1 番地、 2 番地・・・というように 住所が割り当てられている この住所をアドレスという。 メモリはデータをしまうもので それを引き出すためには メモリに番号(アドレス)を振っておけばよいな という考えです
メモリとアドレス(ポインターの前 に) 変数を宣言したとき、 変数に自動的に アドレスが割り当てられる 変数の型によって メモリーの容量は 異なります char 型変数は 1 バイト int 型は 4 バイト double 型は 8 バイト となります 変数のアドレスとメモリは セットになっている
演算子の復習 ( enzan.c を見せる) 四則演算 C 言語では「+」「-」「 × 」「 ÷ 」の四則演算を プログラム上では「+」「-」「*」「 / 」で表し ます 「 = 」代入演算子 a=a+1; これは a に1を加えた値を左の a にいれるという意 味 (右の式を計算してから左に代入しますよという 意味) a=a+1; は a++; と書いても同じです a=a-1; は a--; と書いても同じです
ポインター ポインターとはアドレスを格納する変数のこと ポインターも変数なのでポインタのアドレスとメモ リもあり 宣言するときには型も必要です。 ポインタにも int,double,char 型などがあり int 型のポインタ pa とすると、 int *pa; と宣言します。 このとき int 型の変数のアドレスを格納できます。 「 * 」を間接参照演算子といいます。 double 型のポインタ pb とすると、 double *pb; と宣言 します。 このとき double 型の変数のアドレスを格納できます。
#include int main(void){ int a=1; int *pa; pa=&a; printf(" 変数 a のアドレスは %p で、メモリは %d です。 \n",&a,a); printf(“ ポインタ pa のアドレスは %p で、メモリは %d です。 \n",pa,*pa); *pa=2; printf(" ポインタ pa のメモリは %d です \n",*pa); printf(" 変数 a のメモリは %d です \n",a return 0; }
ポインターの使い方 (pointer.c 参照 ) たとえば int 型変数 a のアドレスをポインタに いれたいとします int a=1; ←a のメモリに1を代入 int *pa; ←int 型変数 a を入れたいのでポインタも int 型 pa=&a; ←a のアドレスをポインタ pa に入れる このとき、 a のメモリも pa のメモリに入る よって a のメモリ= pa のメモリ=1となる 「&」は変数 a のアドレスを参照しますよという意味
ポインターの使い方 (pointer.c 参照 ) pa=&a でポインタ pa に変数 a の アドレスとメモリが入りました この pa はポインタのアドレス部を指します ではポインタのメモリを操作してみます *pa=2; ← ポインタのメモリに2を代入した この *pa はポインタのメモリ部を指します。
ポインタの使い方 (pointer.c 参 照 ) *pa=2; ← ポインタ pa のメモリに2を代入す る ポインタ pa と変数 a のアドレスは同じなので *pa のメモリに2を代入すると、 a のメモリに2を代入することと同じである 変数 a のポインタ pa とは変数 a とまったく同じも のなのである
ポインター演習( pointer01.c 参照) ①ポインタ lpa を宣言する ②ポインタ lpa に a のアドレスをいれてくだ さい %p はアドレスを出力するための演算子です
課題:ポインタ lpa を宣言し、 lpa に a のアドレスをいれて ください #include int main(void){ int a; int XXXX;// ポインタ lpa を宣言してください lpa = XX;// ポインタ lpa に a のアドレスを入れてくださ い printf(" 適当な整数値を代入してください \n"); scanf("%d",&a); printf(" 変数 a に %d が代入されました。 \n",a); printf(" 変数 a のアドレスは %p です。 \n",&a); printf(" 変数 a を指しているポインタは lpa です。 \n"); printf("lpa のアドレスは %p です \n",lpa); printf("*lpa の値は %d です。 \n",*lpa); return 0; }
課題:ポインタ lpa を宣言し、 lpa に a のアドレスをいれてく ださい #include int main(void){ int a; int *lpa; lpa = &a; printf(" 適当な整数値を代入してください \n"); scanf("%d",&a); printf(" 変数 a に %d が代入されました。 \n",a); printf(" 変数 a のアドレスは %p です。 \n",&a); printf(" 変数 a を指しているポインタは lpa です。 \n"); printf("lpa のアドレスは %p です \n",lpa); printf("*lpa の値は %d です。 \n",*lpa); return 0; }
解答( pointer01kai.c 参照) int a; で int 型変数 a を宣言。 int *lpa; で int 型ポインタ lpa を宣言。 lpa=&a; で lpa に a のアドレスを代入する(型はお互 い int ) 「 & 」はアドレス演算子と呼び変数のアドレスを参照 する。 この式は a のアドレスとメモリをポインタ lpa に代入 printf(“%p”,&a); printf で %p を使えば a のアドレスを出力できる。 printf(“%p”,lpa);←lpa でポインタのアドレスを参照す る。 このとき、 a と lpa のアドレスが一致することがわかる。 ポインタ lpa のメモリーを出力するには int 型ポインタ なので printf(“%d”,*lpa); であらわす。 *lpa でポインタのメモリを参照する。
ポインタの関数 ポインタが一番有効な使い方ができるのは関数である。 どんな利点があるかというと 自作の関数内で main 関数内の変数を操作できる ことである。 C 言語で main 関数内の変数を外から操作するには ポインタを使うしかない これは変数のスコープ(範囲)というものが関係して いるが 時間に余裕があれば説明する
#include void swap(int *,int *); int main(){ int a=1,b=2; printf("a=%d,b=%d\n",a,b); swap(&a,&b); printf("a=%d,b=%d\n",a,b); return 0; } void swap(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; }
ポインタの関数の使い方 ( swap.c 参照) たとえば、 void 型関数 swap にポインタを入れるとき int 型ポインタ a 、 int 型ポインタ b を次のように宣言し ます void swap(int *,int *); 関数の引数はポインタのデータ型( int )に「 * 」をつけ ます main 関数内で swap 関数を使うときは 関数の引数 a,b がアドレスであることに注意 swap(a,b); そして、 swap 関数を書くときは次のように書きます void swap(int *x,int *y){ } swap 関数内の x は a のアドレス、 *x は a のメモリ y は b のアドレス、 *y は b のメモ リを指します
ポインタの関数演習( kansu.c 参照) ① input,swap,output 関数の引数をいれてください ② swap 関数を完成させてください int a,b,*p=&a,*q=&b; でポインタを宣言するとともに 変数 a,b のアドレスをポインタ p,q にいれています
#include void input( XXXX, XXXX );// 引数をいれてください void swap( XXXX, XXXX);// 引数をいれてください void output( XXXX, XXXX);// 引数をいれてください int main(){ int a,b,*p=&a,*q=&b; input( X, X);// 引数を入れてください output( X, X);// 引数をいれてください swap( X, X);// 引数をいれてください output( X, X);// 引数をいれてください return 0; } void input(int *x,int *y){ printf("a の値を代入 \na="); scanf("%d",x); printf("b の値を代入 \nb="); scanf("%d",y); } void swap(int *x,int *y){ //swap 関数を完成させてください int temp; XXXX=XX; XX=XX; XX=XXXX; printf("a と b の値を取替え \n"); } void output(int *x,int *y){ printf("a=%d,b=%d\n",*x,*y); }
#include void input(int *,int *); void swap(int *,int *); void output(int *,int *); int main(){ int a,b,*p=&a,*q=&b; // ポインタを宣言すると同時に変数 a と b のアドレスを入れる input(p,q); //input 関数で a と b の値を入力する output(p,q); //output 関数で出力 swap(p,q); //swap 関数で a,b の値を取替える ( 演算する ) output(p,q); //output 関数で出力 return 0; } void input(int *x,int *y){ printf("a の値を代入 \na="); scanf("%d",x); printf("b の値を代入 \nb="); scanf("%d",y); } void swap(int *x,int *y){ int temp; // メモリ一時格納用変数 temp=*x; //*x=*p=a のメモリを temp に一時格納 *x=*y; //*x=*p=a に *y=*q=b の値を代入 *y=temp; //*y=*q=b に temp=a の値を代入 printf("a と b の値を取替え \n"); } void output(int *x,int *y){ printf("a=%d,b=%d\n",*x,*y); }
解答( kansukai.c 参照) swap 関数で演算を自作関数で行います output 関数で出力を自作関数で行います ポインタを使うと main 関数を変数宣言と 自作関数だけ終わらせることができます 長いプログラムになると関数でプログラムを input 関数で入力を自作関数で行います 分解して入力、演算、出力を別々に作ったほうが 間違いがみつけやすく、直しやすくなります。
\ ( ^ o ^ ) / これで C 言語講座は終了で す 皆さんお疲れ様でした