C言語のポインタについてわかりやすく解説してみた
18/11/18 15:28:21 19/05/05 15:34:33
ポインタの概念はC言語特有のものではありませんが、現在主流のプログラミング言語のなかでプログラマーがポインタを意識してプログラミングを行うのはC言語くらいでしょう。
しかし、C言語でポインタの学習をしておくとプログラミング全般で役立ちます。というのも、そもそもポインタとはメモリ上のアドレスを指し示すものです。プログラミングによって記述された処理はすべてメモリ上のどこか、つまりアドレス上で実行されています。
たとえば、変数を用意すればそれもどこかのアドレスに配置されています。現在主流のJavaやPHPなどでは、記述した処理がメモリ上のどこで実行されたか意識することはないでしょう。
C言語でも厳密にはメモリ上のどこかは意識しないのですが、ポインタを用意することで、アドレスを保持することができます。詳細は後述しますが、情報処理試験を受けたことのある方はそれをイメージするとわかりやすいです。
連想配列などでキーと値をセットで格納する概念に少し近いのですが、ポインタはたとえば変数の場所をそのまま保持するという点で違いがあります。
目次
ポインタのサンプルコード
ポインタの概念は上記の通りで、アドレスを格納する変数です。実際のソースコードで確認するとわかりやすいのですが、具体的には以下のようになります。
#include <stdio.h>
int main(void) {
int num = 1; // int型変数
int *p_num; // int型ポインタ変数
p_num = # // ポインタ変数p_numに変数numアドレスを代入
printf("int型変数numの値:%d\n", num);
printf("int型ポインタ変数:%p\n", p_num);
return 0;
}
上記のソースコードを実行すると、以下のようにコンソール出力されます。
int型変数numの値:1
int型ポインタ変数:0x7ffd0a0ecc6
注意点としては、まずポインタ変数を宣言する際は、「*」を前に付けます。上記のソースコードでは、「*p_num」と記述しています。次に、ポインタ変数にアドレスを格納する際は変数名の前に「&」を付けます。
「&」を付けることで、その変数のアドレスを指し示します。この二つがわかれば、上記のソースコードは非常にシンプルで簡単なものかと思います。もう一点知っておいた方が良いこととしては、「*p_num」というようにアスタリスクを付けることで、出力処理等の処理を行う際にポインタの先の値に対して処理を加えることが可能です。
逆に値の格納された変数に「&」を付けるとその変数のアドレスを示すことになります。上記の例で出力してみるとわかりやすいでしょう。
#include <stdio.h>
int main(void) {
int num = 1; // int型変数
int *p_num; // int型ポインタ変数
p_num = # // ポインタ変数p_numに変数numアドレスを代入
printf("int型変数numのアドレス:%p\n", &num);
printf("int型変数numのアドレス先の値:%d\n", *(&num));
printf("int型ポインタ変数p_numの参照先の値:%d\n", *p_num);
return 0;
}
上記のソースコードを実行すると、以下のようにコンソール出力されます。
int型変数numのアドレス:0x7ffd0a0ecc64
int型変数numのアドレス先の値:1
int型ポインタ変数p_numの参照先の値:1
出力処理以外は最初のソースコードと同じです。「&num」は変数の格納先のアドレス、「*(&num)」は変数の格納先のアドレスのなかの値、というややこしい書き方ですが、最終的に値になります。あまりこのような書き方をすることはないでしょう。最後に、「*p_num」はポインタの元の値になります。
ポインタ変数に付けるのか普通の変数に付けるのか混乱することがあるかもしれませんが、「&」を付けるとアドレス、「*」を付けると値、と覚えておくと良いかと思います。そのように覚えておけば、ポインタ変数にそのまま「&」を付けても意味がないことや、値の格納された変数に「*」を付けても意味がないことが自然にわかります。
ポインタの演算で配列の要素を操作する
ポインタは特に配列を操作するのに便利です。なぜなら、配列の要素格納先はアドレスが連続しているからです。
#include <stdio.h>
int main(void) {
int intArray[] = {0, 1, 2, 3, 4};
int *p_int; // int型ポインタ変数
// ポインタにアドレスを代入
p_int = intArray;
printf("int型ポインタ変数p_int:%p, アドレス先の値:%d\n", p_int, *p_int);
printf("int型配列要素intArray [0]のアドレス:%p, アドレス先の値:%d\n", & intArray r[0], *(& intArray [0]));
printf("int型ポインタ変数(p_int + 1):%p, アドレス先の値:%d\n", p_int + 1, *(p_int + 1));
printf("int型配列要素intArray [1]のアドレス:%p, アドレス先の値:%d\n", & intArray [1], *(& intArray [1]));
return 0;
}
int型ポインタ変数p_int:0x7fff3e4c1100, アドレス先の値:0
int型配列要素intArray [0]のアドレス:0x7fff3e4c1100, アドレス先の値:0
int型ポインタ変数(p_int + 1):0x7fff3e4c1104, アドレス先の値:1
int型配列要素intArray [1]のアドレス:0x7fff3e4c1104, アドレス先の値:1
配列に対してポインタ変数を設定した場合、自動的に配列の先頭のアドレスとポインタが一致します。int型の配列は、ポインタ変数を1加算すると4増えます。なぜなら、int型の変数1個で4バイトのアドレスを使用しているからです。
ポインタのポインタ
ポインタは上記の通り変数のアドレスを格納するための変数ですが、そのポインタ自体もどのかのアドレスに格納されます。つまり、ポインタが格納されたアドレスをさらにポインタ変数で指定することも可能なのです。
具体的には以下のサンプルコードのようになります。
#include <stdio.h>
int main(void) {
int num = 1; // int型変数
int *p_num; // int型ポインタ変数
p_num = # // ポインタ変数p_numに変数numアドレスを代入
int **pp_num; // int型ポインタ変数のポインタ
pp_num = &p_num; // ポインタ変数のポインタpp_numにポインタ変数p_numのアドレスを代入
printf("int型変数numの値:%d\n", num);
printf("int型ポインタ変数p_num:%p\n", p_num);
printf("int型ポインタ変数のポインタpp_num:%p\n", pp_num);
return 0;
}
上記のソースコードを実行すると以下のようにコンソール出力されます。
int型変数numの値:1
int型ポインタ変数p_num:0x7ffef434156c
int型ポインタ変数のポインタpp_num:0x7ffef43415
混乱してきそうな感じがしますが、一つづつ落ち着いてトレースすれば理屈としては単純です。一つ目のポインタの宣言から格納までの処理は今までのソースコードと同じで、二個目のポインタに格納する際に一つ目のポインタを普通の変数のように扱っているだけです。
ポインタの説明は以上のようになりますが、最初は混乱するかもしれません。しかし何度か使用していれば慣れるので、最初からすべて理解しようとするよりは、だいたいの概要を掴めば最初は良いかと思います。
案件量が豊富なアルマサーチ
最後に、アルマサーチのご紹介!
アルマサーチはフリーランス向けに案件をご紹介することに特化したエージェントサービスです。豊富な案件量から、安定して継続的な案件のご紹介を実現しており、口コミから登録エンジニアが急増中です。
アルマサーチが選ばれる理由
- 豊富な案件量。週3?4日の案件や在宅リモート案件も。
- 優秀なコンサルタント陣。
- 案件に参画後もしっかりサポート。
豊富な案件量
フリーランス向けに特化し、業界屈指の案件量を誇ります!週3?4日の案件や、在宅リモート案件もありますし、その他あらゆる希望をしっかりお伝えください。最適な案件のご紹介をさせていただきます。
優秀なコンサルタント陣
技術に疎く、開発の希望を伝えても響かないエージェント・・・嫌ですよね。アルマサーチにはそのような者は一切おりません!さらに独立にまつわる税金や保険関係に詳しいスタッフが徹底的にサポートさせていただきます。
案件に参画後もしっかりサポート
常駐先が決まった瞬間に、一度も連絡が取れなくなるエージェント・・・いますよね?アルマサーチでは、そのようなことは一切ありません!常に電話やメールは即対応しますし、月に1度のランチミーティングなどから現場の状況を細かくヒアリングし、就業環境改善に尽力いたします。
人気記事