Summary
2022年前半にコンピュータサイエンス初学者としてCS50を一通り実施。すべて無料で初学者向けの大学の授業を受けられるという素晴らしいサービス。そのなかで、Week1-5はC言語、Week6以降はPythonを学ぶのだが、個人的に躓いたC言語のポインタについてメモ
内容
ポインタとはなにか
C言語のポインタ(pointer)とは、データを指し示す(参照する)値で、データが格納されているメモリの位置(メモリアドレス)のこと。(人を指す「人差し指」は英語で pointer finger、人差し指で「あの人です」と人を指し示すことができる)
ポインタ変数はメモリアドレスを格納できる変数で、データがどこにあるかを指し示すことができる。
int c =3; // int変数cを宣言し、値として3を格納
int *p = &c; // ポインタ型変数pを宣言し、変数cのメモリアドレスを格納 (0x0eff1018のような値)
変数c
はint型変数として定義され、変数の値としてint型データ3
を格納している。
変数p
はint型データを指し示すポインタ型変数として定義され、3
が格納されている変数c
のメモリアドレスを格納している。(ポインタ変数の定義方法は変数名の前に*
を指定し、変数のメモリアドレスは変数名の前に'&'を指定する)
変数の値を参照するとき、変数名の前に*
を指定することでポインタ変数の参照先データを表すことができる。*p
の値は3
となる。
(*
を付けない単なるp
の値は上記コメントに書いた0x0eff1018のような値)
なぜ必要なのか
そもそもコンピュータとはバイナリコードを実行して動いてる(バイは2、バイナリは2進数)
バイナリコード:0101010…
これはなぜかというと、コンピュータがもともとは0、1の入力に合わせて出力を変える論理ゲートによって作られ、論理ゲートの集合体がレジスタ・カウンタ、そしてCPUとなっている。そのため、なにかデータを保存するときも例えば日本語や数字をそれぞれバイナリに変換した上で、CPUの特定の場所に保存を行っている。その場所を示しているのがポインタである。
逆に保存する場所がない、となるとメモリ不足となりCPUは処理を行えない(スタックオーバーフロー)。PyothonやJSなどコード実行におけるメモリの割当を自動で行うため、気にしなくても良いが、C言語は自分でメモリを指定し場所を確保する必要がある。
ポインタによってできること
データに直接触れることなく(例えば関数の外などから)データの内容を操作することが可能
ポインタを使うことによりData Structureを作成、操作することが可能
特に後者のデータストラクチャについては最初理解が難しいが、データを効率的に読み込み、保存、利用(検索など)するためのデータ保存方法と理解した。代表的なData Structureは4種類ほどあり、Linked DataやHash table、B-treeなどがある。なぜポインタが関わってくるかというと、例えばLinked listでは一つのデータの中に次のデータの位置を示すポインタを入れておくことにより、データごとの順序を作ることが可能。
躓いたポイント
ポインタが何を示しているかはおおよそ分かるが、その具体的な使い方やなぜ必要なのか、がはじめ全く理解できなかった。そもそもメモリを割り当てる、Data Structureを作る、というのが他言語だと自動化されていることも多く、その理解からする必要があった
ただしこの理解は、Conputer Scienceをさらに学んでいく上でもとても有益だったため、個人的には非常に良い学びであった
学習に当たり参考にしたサイト
- CS50
- Youtube 河口研チャンネル・Kawaguchi Lab
https://www.youtube.com/watch?v=t9DpkD1zHPw