はじめに
現在参画中のプロジェクトでC++のソースコードを理解する必要があります。
その為、C言語の特徴を理解するためにこの記事を作成しました。
最初にC++のソースを見たときは、
「んー?基本はJavaと似たようなもんでしょ。いけるっしょ」
と舐めまくってましたw
いざ読んでみると、
「ヘッダー?ポインタ?」
「、、、この星みたいなヤツなに?…w」
なんとなく全体像は分かるんですが(コメントアウト読んでるだけw)
メソッドの深くまで追っていくと、もーわけわかりません!
これは基礎から学び直さないと絶対に理解できんな!ということで、
一番わけのわからない
「ポインタ」と「アドレス」についてまとめてみました。
C言語とは
1972年に開発された歴史あるプログラミング言語のひとつ。
最近はJava, PHP, Rubyの次くらいに開発で使われている言語のようです。
もう50年使われている言語なんですね!すげぇ…
主な特徴4つ
手続き型言語
- 構造がシンプル。
- 上から下に処理が流れていくことが多いためソースコードの流れを理解しやすい。
処理速度が速い
- 特にC言語はコンパイラ言語のなかでも処理速度は最速ともいわれている。
どのような環境でも実行できる
- マルチプラットフォームであるため、環境に依存せずに実行できる。
- どのような実行環境にも実装できるため、特に組み込みの分野で強みを発揮する。
さまざまな分野に応用されている
- OS開発からソフトウェア、スマホアプリ、組み込み制御機器、車載機器、IoTやAI、ロボットの制御など、非常に多岐にわたる分野でC言語が採用されている。
習得するのが難しい
- コンピューターを構成するメモリやCPUといったハードウェアに関する周辺知識も必要。
- C言語にハードウェアを制御する要素があり、コンピューターを構成するメモリやCPUといった部分の知識が必須となるため。
- ポインタ、アドレスの概念が理解しづらい。(これは個人的な意見w)
C++
- C言語の開発から約10年後の1983年に作られたプログラム言語。
- C言語の機能を拡張し「オブジェクト指向」という概念を取り入れた。
- プログラミングの難解さを大部分解消し、容易にした。
C#
- マイクロソフトによって開発されたプログラミング言語。
- C++のようにC言語との互換性はなく、まったく別のプログラミング言語。
- C++とJavaの分かりやすい部分や便利な部分が取り入れられている。
まずは画像でイメージ
簡単なソースでイメージ
#include <stdio.h>
int main() {
int a = 3; // 変数a宣言して初期化しただけ
int *p; // ポインタ変数の宣言 (なんやこれw)
p = &a; // 変数aのアドレス(メモリの中の住所)をpに代入
printf("変数aの値 %d\n", a);
printf("ポインタ変数pの値 %d\n", *p);
printf("変数aのアドレス %p\n", &a);
printf("ポインタ変数pのアドレス %p\n", p);
return 0;
}
変数aの値 3 // これは分かる
ポインタ変数pの値 3 // aのアドレス(&a)の中身を見に行っている(*p = &a)から上と同じく3
変数aのアドレス 0012FF88 ← 実行環境によって表示されるアドレス値は変わります。(aの住所をだから値じゃないよ)
ポインタ変数pのアドレス 0012FF88 (p = &aだから同じだね)
アドレス
アドレスって住所ってことっすよね?
ということはなんかの場所を示してるということですな。
普段なんとなく、int a;
と変数宣言していたのですが、
これは a という変数を宣言する時に、メモリの領域を確保しているそうです。
(メモリなんて概念をそもそも知らんかった!w)
コンピュータはプログラム内の変数をメモリー上に確保し、その場所を特定するためのアドレスを記憶している。
上のコードでいうと変数 a
のアドレスは0012FF88
になります。
ポインタ
簡単に言うと、アドレス(住所)を指し示すための変数です!
んーーといってもこれだけではイメージが付かない…(説明するって難しいですねw)
ポインタは、英語で「ある場所を指し示す人や物」という意味。
つまり、ポインタ型の変数を宣言するということは、「0012FF7C」だとか、 「0064FDF4」という住所を指し示す値を入れる箱を用意することを意味する
んーーこれでもなんかしっくりこない…
以下のソースコードを見ると、
ポインタを使うことで間接的に値の代入をすることができると分かります。
main()
{
int a=1, b=2;
int *p; // ポインタの宣言
printf("初期値: a = %3d , b = %3d\n", a, b);
p = &a; // a のアドレスを代入(a を参照)
*p = 100; // a への間接的な代入
printf("結果1: a = %3d , b = %3d\n", a, b);
p = &b; // b のアドレスを代入(b を参照)
*p = 200; // b への間接的な代入
printf("結果2: a = %3d , b = %3d\n", a, b);
}
初期値: a = 1 , b = 2
結果1: a = 100 , b = 2 # *pに代入したハズなのに?
結果2: a = 100 , b = 200 # 〃
ポインタという変数を定義しておいて、
そこに値のアドレスを代入することで、間接的に値を変更できることは分かりました。
ポインタを使うことで、もっと実践的にはどのようなメリットがあるのかを調べていきたいです。
まとめ
- アドレス・・・メモリの中のある住所を指している。
- ポインタ・・・アドレスの中の値を指している。
いやざっくりすぎーw
参考資料
C言語のポインタを日本一わかりやすく解説する〜導入編〜
初心者向け】ポインタはなぜ難しいか(ポインタのちょっとしたコツ)
【新しいC言語講座】ポインタの基本(2)
C言語:ポインタの概念の図解
C言語のポインタとは?基本的な記述法と配列、構造体、関数への渡し方
C言語とは?特徴や作れるものを入門者向けにわかりやすく解説
C言語とは?特徴やできることをわかりやすく解説
C言語とは?|知っておきたいプログラミング言語の特徴を徹底解説
C言語ポインタのしくみ-コンピュータのしくみとポインタの関係 -
おわりに
アドレスとポインタについてまとめてみました。
基本くらいしかまだ理解できていないので、
業務で実際のコードを見たらまだまだ分からないことばかりですw
色んな記事と参考書を読んで自分なりにまとめると、
ちょっと理解が進みました。
なかなか分かりにくい記事だと思いますが、
最後まで読んでいただきありがとうございました。
毎週新宿でもくもく会を主催しております!
気になる方はお気軽に参加してみてください~(/・ω・)/
https://shinjuku-realize0707.connpass.com/