✍️

Java・PHPプログラマーがポインタを勉強してみた

2024/07/18に公開

はじめに

してみた・・といいつつ、全く初めて覚えたわけでもありませんが、アドレスの考え方が必要な業務がありましたので、改めてC言語の入門書を読み直したりしていました。

そこで、JavaやPHP・JavascriptプログラマーなどでもC言語のポインタを知っておくとより深くプログラミングが分かるという事を書いてみました。

ポインタとは

ポインタとは変数のアドレスを扱うものです。
はるか昔から非常に難解で高度な技術と言われてきました。

しかし、実はC言語のポインタ構文自体はJavaをひと通り扱えるレベルであればすぐ覚えられるものです。

main.c
#include <stdio.h>

    int main () {
        int num = 100;
        int* pointerOfNum = &num;

        printf("numはメモリアドレスの%p番地にあります。",pointerOfNum);
        printf("numの値は%dです。",*pointerOfNum);

        return 0;
    } 

これを実行すると、numのアドレスと値が表示できます。

numはメモリアドレスの0x7ffede871368番地にあります。numの値は100です

この記事はC言語の解説ではありませんので、理解できなくてもかまいませんが、簡単に説明します。

&numのように、変数の頭に&をつけるとその変数のメモリアドレスという意味になります。

で、その&numを代入している pointerOfNumが int*型のポインタです。
それ以降はそのポインタを使って値取り出したり書き換えたりできるという事です。

ね、簡単でしょう?

変数宣言とは何だったのか。

さて、私たちは日々のプログラミングで変数を宣言しています。
宣言しなくてもコンパイラが解釈して暗黙に宣言する言語もありますが、それも含めて。

Aさん 「入門書におまじないでやれって書いてあったから宣言してる」
まあ、そうですね。はじめはそれでもいいと思います。

Bさん 「変数宣言しないと型が把握しずらくて後が大変」
はい、それもその通り。

ですが、今回ピックアックするのはこの機能。
変数宣言する事で、メモリ領域に値を書き込むスペースを確保する です。

大抵の初心者向けプログラミング入門書には、変数は値を入れる事ができる箱のような挿絵が入っていますね。
その、「この箱を作る」というのをより物理的に言い換えるとメモリ領域を確保する。
という事なんです。

それで、箱の大きさをどうするかが変数の型によって決まります。
言語によって違いますが、int型は4バイトとか、long型は8バイトとか。
メモリっていうのは1バイトが1マスの小さな収納マスが直列に並んでいるって事なんです。

だから、変数を宣言するってことは、このメモリのここのマスからここのマスまではこの変数が占拠しました!
他の変数は使うなよ!ってやってるんですね。

JavaやPHPのような高級言語にポインタがないのは、この変数が確保した領域には絶対に他の変数と陣地の取り合いをしたりしないようにするためです。

逆にいえばC/C++言語が上級者向けと言われるのは、ポインタに間違えて変なアドレスを代入したせいで、本来ありえない値を書き換えてしまう危険性があるからです。
(一例なので他にも難しいところはたくさんあるでしょうが)

Nullとはなんだったのか

JavaやPHPやってると、嫌というほどNullPointerExceptionに遭遇すると思います。
通称ぬるぽ。

これってどういうエラーですか?
「変数を初期化せずに参照すると出るやつですね」
はい、そうです。

じゃあ、変数を初期化するってどういうこと?
ここまで読んだらわかりますよね。
そうです。メモリ領域を確保する、ということです。
もちろん初期値を代入しておくことも初期化という言葉を使いますし、そちらの方が普段イメージしている初期化に近いと思います。

でも、それだと0や空文字、空のオブジェクトとNULLの違いって説明しずらいですよね。

変数の中身を読み書きするためには、その変数がメモリのどこの番地に住んでいるかを知る必要があります。
NullPointerExceptionとは、宛先の書いていない手紙を届けてくれとポストに投函したようなものです。
郵便局員はそんな手紙渡されても届けられるわけがありませんね。

配列とはなんだったのか

同じ種類の変数をリスト状にして繰り返し処理に使ったり、便利な配列。
これもポインタを勉強すると習います。

配列とはメモリアドレスに連続して同じ型の箱を並べた領域のことです。
そこでC言語では配列の先頭アドレスから、何マス隣かという書き方で配列内の値のアドレスを特定できます。

JavaやPHPではもっとわかりやすく$array[5] なんていう書き方で読み書きできるようになっていますが、この添字はそういう意味だったのです。

ただし、最近の言語では内部的にもっと最適化していたりするので、隣続きで並んでいるとは限らないと思います。
少なくともC言語の世界ではアドレスを増減することで配列を表現できていたってことです。

マンションやアパートの住所を想像するとわかりやすいと思います。
あるマンションの101号室がわかれば、隣の部屋は102号室だとだいたいわかりますよね。

おわりに

いかがだったでしょうか。
昔はポインタと聞くだけでアレルギー反応を起こすプログラマーが多かったようですが、意外と親しみが湧いてきたのではないでしょうか。

Cはアセンブリのような低レベル言語をWeb系プログラマーが使うことはほぼありませんが、コンピュータの本質を知るにはいい教材になります。
気が向いたら読んでみてはいかがでしょうか。

株式会社ONE WEDGE

【Serverlessで世の中をもっと楽しく】 ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
https://onewedge.co.jp

Discussion