概要
最近、アルバイト先や趣味でGolangを書いたり、学校の講義や課題でC言語を書いたりする中でやっぱりポインタって分かりにくいな〜と思い、その話をいろんなエンジニア学生とすると、やっぱりみんなわかりにくいと思っていたので今回はC言語でのポインタ(GolangはC言語を参考に作られた)をまとめてみました!!!
ポインタとは
コンピュータというのはプログラム内の変数をメモリ上に確保して、その場所を特定するためのアドレスを記憶しています。プログラムでそのアドレスを取り扱いたい時に使用するのがポインタです。つまり、ポインタというのはアドレスを取り扱う変数のことを言います。
構文
C言語でポインタを使用する際の構文についてみていきます。
ポインタの宣言
データ型 *ポインタ変数名;
(例)int型変数のポインタを宣言する
int *p;
アドレスを代入
- 変数に"&"をつけるとそのアドレスが取得できる。
&変数名
(例)
#include<stdio.h>
int main() {
int x = 1;
int *p;
p = &x;
printf("「&x」のアドレス: %p\n", &x);
printf("「p」が示すアドレス: %p\n", p)
return 0
}
(実行結果)
「&x」のアドレス: 00A2EE76
「p」が示すアドレス: 00A2EE76
ポインタが示すアドレス内の値を表示
- ポインタに"*"をつけるとポインタが示すアドレス内の値が取得できる。
*ポインタ変数名;
(例)
#include<stdio.h>
int main(){
int x = 1;
int *p = &x;
printf("「p」が示すアドレス内の値: %d\n", *p);
return 0;
}
(実行結果)
「p」が示すアドレスの値: 1
注意すべきこと
注意点 1
混乱しやすく注意が必要だと考えるのが、"*"の解釈の仕方についてです。
ポインタの宣言時にアドレスを代入する場合、「int *p = &x」となっているので、「*p」に「&x」を代入しているかのように見えるが、意味的には「p = &x」となるのです。つまり、以下の二つは同義です。
int x = 1;
int *p;
p = &x;
int x = 1;
int *p = &x;
注意点 2
二つ目の注意すべき点としては、初期化についてです。ポインタ変数の宣言をするだけでは、そのポインタ変数が示すアドレスは不定となるのです。そのためポインタ変数を初期化しないで使用すると不特定のアドレスにアクセスすることになり、バグが発生する原因になります。
#include<stdio.h>
int main() {
int x = 1;
int *p;
// 以下の一行は p を初期化していないのでバグの原因になります
*p = x;
}
配列とポインタ
配列の先頭アドレスをポインタ変数に代入することによりポインタ演算を使って配列を取り扱うことができるのです。以下のサンプルを見るとわかるように、 &num[0]
と num
は同じである。
また、 *(p + i)
と num[i]
は同じである。
#include<stdio.h>
int main() {
int *p;
int i;
int num[3] = {1, 5, 10};
// 以下の一行は配列の先頭アドレスをポインタ変数に代入
p = num;
for(i = 0; i < 3; i++) {
printf("%d\n", *(p + i)); //ポインタを要素数分進めて値をとる
}
return 0;
}
(実行結果)
1
5
10
#まとめ
今回はC言語でのポインタについての基本的な勘違いしやすい点を中心にまとめました。次回は、Golangのポインタについての勘違いしやすい点についてまとめていこうと思います。!!!