奥深くて大変なポインタですがまずは簡単なところだけやります。 この章を読む前に入力の章の&の意味の項目を読んでおいてください。 そこに書いてあったように変数はその中身と中身が格納されている場所という二つの情報を持っています。 今までは中身のみを扱っていましたが今度は格納場所の方を扱います。
格納場所を値として持つ変数をポインタ変数といいます。
宣言時に変数名の前に*をつけるとその変数はポインタ変数となります。
int *p; //int *型のpを宣言する感じ
これでpは他のint型の変数の場所を覚えさせる変数となりました。
pに変数aのアドレスを代入してやるとpはaを指すようになります。
int a=5,*p;
p=&a;
ポインタの指している変数の中身はポインタの前に*をつけて表します。
宣言の時の*とは意味が違うので気をつけてください(宣言の時の*はその変数がポインタ変数であること表し、普段はポインタが指している変数の中身を表す)。
上の例なら*p=5となっています(指している変数aの中身)。
一度p=&aとやっておけばpはaを指し続けるので後からaの値を変えても*pの値も同時に変化します。
pはaの値を覚えているのではなく場所を覚えているのでありaの値を変えてもaの保存場所は変わらないので*pは常にaと同じ値をとり続けるということです。
また*pになにか代入するとaも変化します。
これは*pへの代入がpの指す場所をいじるということだからです。
これが他の変数を指しているという状態です。
普通、変数の値は各関数ごと独立です。
例えば
void set10(int x)
{
x=10;
}
int main(void)
{
int a=0,b=1,c=2,x=3;
f(a);f(b);f(c);f(x);
printf("%d %d %d %d",a,b,c,x);
return 0;
}
のようにしてもset10は渡された変数に10を代入する関数としては機能しません。
結果は宣言時の値がそのまま表示されるだけです。
名前が同じxですら何の作用も受けません。
set10の中で新たにxという保存場所をつくり元の値をコピーしてつかっているのでそれをいくらいじってもオリジナルは全く変化しないということです。(set10内のxとmain内のxも名前が同じだけで保存場所は異なる全く別の変数。)
そこが関数の便利なところなのですが今回はあえてオリジナルの方を関数の中から変えてしまうものをつくってしまいます。
void set10(int *x)
{
*x=10;
}
int main(void)
{
int a=0,b=1,c=2,x=3;
f(&a);f(&b);f(&c);f(&x);
printf("%d %d %d %d",a,b,c,x);
return 0;
}
ちょっと変えただけですがこれでOK。
今度はxがオリジナルの方を指しているので別の関数の変数だろうが値をいじれます。
なお引数がポインタな関数にアドレスを渡すとき*xに&aなどを代入しているように見えてしまって混乱しやすいのですが(ていうか私は昔この勘違いのせいでポインタを理解できなかったのですが)これはint *型のxに&aなどを代入しているのです。
もう一度いいますが宣言時の*は指している中身を示す*とは意味が違います。
二変数のアドレスを受け取りそれらの値を交換する関数をつくりましょう。
void swap(int *a,int *b) { int c; c=*a; *a=*b; *b=c; }