C言語、学びはじめました
とあるイベントに参加したことをきっかけにC言語を勉強しています。 自分自身も手探りで学んでいる最中ですが、C言語を勉強する上で学習コストの高いポインタについて、今の状態でわかっていることをまとめておきます。
間違いやより適切な表現等のご連絡、ご相談はこちらのリンクよりお願いいたします。
ポインタとは
ポインタは、メモリ上のアドレス(場所)を格納する変数です。通常の変数が「値」を持つのに対し、ポインタ変数は「値が格納されている場所」を持ちます。
例えるなら:
- 通常の変数 = 家の中の物
- ポインタ = 家の住所
住所がわかれば、その家に行って物を取り出したり、置いたりできる、という感じで理解しています。
ポインタの長所:関数を超えて変数を操作できる
C言語では、通常、関数に変数を渡すと「値のコピー」が渡されます。そのため、関数内で値を変更しても、呼び出し元の変数には影響しません。
しかし、ポインタを使えば、関数を超えて元の変数を直接操作できます。これがポインタの使いどころになってきます。
サンプルコード
では、実際のコードで確認してみましょう。
| |
実行結果(例)
実行環境によってn adressとnb valueは変動すると思いますが、値は同一になっているはずです。
ちなみに自分の実行環境はOS: Ubuntu 24.04.3 LTS x86_64、コンパイラはcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0、cc -Wall -Wextra -Werrorオプションでコンパイルしています。
| |
コードの詳細解説
1. 各種変数の宣言と初期化
main関数の中から見ていきます。
| |
int *nbの*は「ポインタ型」を示します&nは「変数nのアドレスを取得」する演算子です- これで
nbは変数nの場所を「知っている」状態になります
2. ポインタが指す先の値を確認
| |
*nbは「ポインタnbが指す先の値」を意味します(間接参照)- この時点では
nの値である32が表示されます
3. アドレスの確認
| |
両方とも同じアドレスが表示されます。これは nb が正しく n を指していることを示しています。
4. 関数を超えて変数を操作
| |
ここでは、main関数の外に出てsingle_pointer 関数に nb(=変数nのアドレス)を渡しています。
single_pointer関数内では:
| |
*nb = 42 により、ポインタが指す先、つまり main関数内の変数nの値が直接変更されます。
5. 結果の確認
| |
関数実行後、変数 n の値が 32 から 42 に変わっていることが確認できます。
メモリのイメージ図
| |
ポインタ関連の演算子
| 演算子 | 名前 | 意味 | 例 |
|---|---|---|---|
* | 間接参照演算子 | ポインタが指す先の値にアクセス | *nb = 42 |
& | アドレス演算子 | 変数のアドレスを取得 | nb = &n |
なぜポインタが必要なのか?
1. 関数から複数の値を返せる
通常、関数は return で1つの値しか返せませんが、ポインタを使えば複数の値を変更できます。
| |
上記のコードだと、void型なので直接には何も値は返りませんが、sumとproductの値は変更されるので二種類の変数が「返って」いることになります。
2. 大きなデータを効率的に扱える
構造体や配列など大きなデータをコピーせず、アドレスだけを渡すことで処理が高速になります。
3. 動的にメモリを確保する際に使う
malloc などで動的にメモリを確保する際、ポインタが必要です。
まとめ
- ポインタは変数のアドレス(場所)を格納する変数
&でアドレスを取得し、*で指す先の値にアクセス- 関数を超えて変数を直接操作できるのが最大の利点
- メモリを効率的に扱うために不可欠
自分でも書いていて迷子になりかけていますが、だいたい「住所を教えて、その場所の物を操作する」というイメージで理解しています。実際にコードを動かして、アドレスと値の変化を確認してみてください!
おすすめサイト
ここまで読んでいただいて元も子もない気がしますが、個人的にC言語を勉強するにあたって一番おすすめのサイトがあります。
文量は長めですが、その分初心者でもわかりやすくポインタを理解できるサイトになっています。
最初の最初はこの記事から読むと良さそう→【C言語】ポインタを初心者向けに分かりやすく解説 | だえうホームページ
以上