ポインタとは
C言語学習者の多くが挫折する原因の一つが、このポインタだと思います。
しかし、幸運なことに前回の記事を読んだ人はポインタの基礎を理解できています。
ポインタは、一言で言えばアドレスを格納する変数のことです。
また、ポインタの型をポインタ型ともいいます。
ポインタを使ってみる
以下のコードを実行してみましょう。
#include <stdio.h>
int main() {
int *p;
int a;
p = &a;
printf("%p\n", &a);
printf("%p\n", p);
return 0;
}
出力結果は以下のようになります。
0x7ffdcf492efc
0x7ffdcf492efc
ポインタ型は、以下のように宣言します。
型 *変数名;
上記のコードでは、int のポインタ型変数の p に a のアドレスを代入して、a のアドレスと p の中身を出力しています。
ポインタを使って変数の値を変える
ポインタ型の変数の前に * (アスタリスク)をつけることで、格納しているアドレスにある値を参照することができます。
以下のコードを実行してみましょう。
#include <stdio.h>
int main() {
int *p;
int b;
a = 3;
p = &a;
printf("%d\n", *p);
return 0;
}
出力
3
a に格納されている値をポインタ型変数である p から参照することができました。
また、ポインタ型変数 p を使用して、a の値を変えることもできます。
#include <stdio.h>
int main() {
int *p;
int a;
a = 3;
p = &a;
*p = 10;
printf("%d\n", a);
return 0;
}
出力
10
ポインタで遊んでみる
ポインタ型変数に入っているのは、アドレスと説明しました。
では、ポインタ型変数に入っているアドレスに 1 を足したらどうなるのでしょうか。
#include <stdio.h>
int main() {
char c;
char *p;
p = &c;
printf("%p (%llu)\n", p, p);
p++;
printf("%p (%llu)\n", p, p);
return 0;
}
出力
0x7ffd39c9c3ff (140725572977663)
0x7ffd39c9c400 (140725572977664)
普通にアドレスに 1バイトが足されました。
では、これをintのポインタ型にしたらどうでしょうか。
#include <stdio.h>
int main() {
int a;
int *p;
p = &a;
printf("%p (%llu)\n", p, p);
p++;
printf("%p (%llu)\n", p, p);
return 0;
}
出力
0x7fff84cd56dc (140735421437660)
0x7fff84cd56e0 (140735421437664)
なんとアドレスには、4バイトが足されました。
これは、ポインタは各型の大きさに応じてアドレスを増やすためです。
先ほど、ポインタ型の前にアスタリスクをつけることで、格納されているアドレスに存在する値をいじれることを学びました。
これを使用すれば、以下のようなこともできます。
#include <stdio.h>
int main() {
int a;
int b;
int *p;
p = &a;
p++;
*p = 12345;
printf("&a: %p (%llu)\n", &a, &a);
printf("&b: %p (%llu)\n", &b, &b);
printf("p: %p (%llu)\n", p, p);
printf("a: %d\n", b);
return 0;
}
出力
&a: 0x7ffd5a46a6d8 (140726118033112)
&b: 0x7ffd5a46a6dc (140726118033116)
p: 0x7ffd5a46a6dc (140726118033116)
a: 12345
最初ポインタ型変数 p に a のアドレスを入れ、1(4バイト)足してポインタ型変数 p に格納されているアドレスを b のアドレスと同じにしました。
そのアドレスに格納されている値を変えることで、bの値を変えたのです。
0件のコメント