C言語のポインタはたくさんの人がつまずくポイントだと思います。

実際に僕もC言語を勉強する過程で、ポインタというものを理解できずに苦しんでいました。

こういう解説があったら、昔の自分が理解できるかな?という考えで解説していきます。

ポインタの概念から使い方まで、全力で分かりやすく解説します。

C言語に関する解説をまとめています
>C言語解説まとめ!

目次

ポインタってなに?

C言語においてポインタとは、メモリの位置を表す仕組みです。

いきなり言われても分からないですよね。

ポインタを理解するためには、少しハードウェアの知識を入れる必要があります。

パソコンの内部には、メモリと呼ばれるパーツが搭載されています。

メモリはCPU(情報を処理するところ)が処理した情報などを一時的に保存しておくことで、パソコンの全体の仕事をスムーズにするパーツです。

メモリの内部にはいくつもの情報を保存しておく部屋が用意されていて、その部屋一つ一つにアドレス(住所)が振り分けられています。
要するに、どの情報をどこに保存しているのかを分かりやすくするためです。

ポインタという機能は、そのアドレス(住所)からメモリ内の情報を探しだし、参照したり、変更したりなどの操作を行えるものです。

基本的にアドレスは16進数で表記されます。
それを格納するためにC言語では特殊な変数を用います。(書き方解説で解説)
C言語では16進数を「0x」を数字の前に付けて表します。

C言語における16進数の扱い方をまとめました。
>【C言語】16進数の扱い方 基本

何に使えるのか

それじゃ実際にポインタって何に使えるの?といった疑問が出てくると思います。

などの用途です。

処理を軽くする

ではなぜ処理が軽くなるのでしょうか。

正直これはポインタを覚える上で必須な知識ではありません。気になる人は見ていってください。

これは一つの例ですが、
C言語には「配列」と言われるものがあります。

ポインタまで勉強している皆さんであればもう使ったことがあるかもしれません。

配列は 配列名[要素数] で表します。

配列の各要素はメモリの隣同士に保存されます。

つまり、配列名のアドレス(先頭アドレス)が分かれば、他の要素のアドレスも分かるということです。

よって、ポインタを用いることで配列名を指定するだけで配列の要素を使用することができるので、コードもそんなに書く必要がなく、コンピュータ側での処理の負担も減るというわけです。

そのような仕組みでプログラムを軽量化することができています。

関数において2つ以上の値を変更できる

皆さんが関数を使ったことがある前提で話します。

関数には「return」という機能があり、関数内で処理した数値のうちの一つをmain関数に返すことができます。

ただ、返せる値は一つだけです。

では、2つ以上の値を関数を用いて変更したい場合はどうすればよいでしょうか。

そこで使用するのがポインタです。

ポインタはアドレスをもとに値を参照できると説明しました。

つまり、関数にアドレスを渡すことで、関数内でそのアドレスを参照して、そのアドレスにあるデータを変更する。そうすることで、returnを使わずとも、いくつかの変数の値を変更することができるということです。

そのやり方は書き方解説で解説します。

ポインタは少し理解が難しいです。説明するのですらとても難しいですから(笑)
最初はだれでも慣れないものですので、諦めずに勉強していきましょう!

書き方解説

いきなりコードを貼っちゃいます。

まず初めにポインタの基本操作のためのコードです。

#include<stdio.h>
int main(void)
{
int a ; //int型変数aを宣言
int *p ; //int型のポインタを格納する変数pを宣言

a = 3 ; //aに3を代入
p = &a ; //pに変数aのアドレスを代入

printf(“変数aの値は%d\n”, a ) ; //aの値を出力
printf(“変数aのアドレスは%p\n”, &a ) ; //aのアドレスを出力
printf(“ポインタpの値は%p\n”, p ) ; //pに入っているアドレスを出力
printf(“*pの値は%d\n”, *p ) ; //pに入っているアドレスが指している値を出力

return 0 ;
}

コピペしたら使えるはずです。(間違えていたらごめんなさい)

一つ一つ解説していきます。

まず初めに、変数の宣言をします。

整数を格納する変数は int 型
ポインタを格納する変数は、変数名の前に「*」(アスタリスク)をつけます。
ここでは変数名を「p」にしていますが、ここは変数名ですので、どんな文字でも問題ないです。英語と数字で作ることだけ気を付けましょう。

次に変数に値を代入します。

aには普通に=整数で代入します。
p = &a ;とすることで、pにaのアドレスを代入することができます。

&a は a のアドレスを表しています。

printfの文を説明していきます。

%pはポインタの変数に格納されているアドレスを出力するためのものです。

1文目

%d を用いて a の値を出力しています。

2文目

%p を用いて a のアドレス &a を出力しています。

3文目

%p を用いて p に格納されているアドレスを出力します。
p には先ほど &a (a のアドレス)を代入しているので、aのアドレスが出力されます。

4文目

%d を用いて p に格納されているアドレス(a のアドレス)が指す値(a=3)を出力します。
つまり、a に格納されている 3 が出力されます。

これらのことから関係をまとめると、

こうなります。(言い回しや属性によって少し異なりますが)

この関係性を覚えておくと、かなりポインタを扱いやすいと思いますので、これは覚えておきましょう。

これでポインタの基本的な操作の説明は終わりです。

2つの値を変更する関数

普通に関数を使い、returnを用いて値を変更する場合は、一つの値しか変更できません

そこで、2つ以上の値を変更したい場合には、ポインタを用いることで、簡単に変更することができます。

例えば、2つの値に5を加えるという関数で考えます。

#include<stdio.h>
void plus(int *x , int *y ) ;
int main( void )
{
int a , b ;
a = 10 ; b = 15 ;

printf(“aの値は%d , bの値は%d\n”, a ,b ) ;

plus( &a , &b ) ;

printf(“aの値は%d , bの値は%d\n”, a ,b ) ;

return 0 ;
}
void plus(int *x , int *y )
{
*x += 5 ;
*y += 5 ;
}

今回、関数にはプロトタイプ宣言を使っています。

コードを一つ一つ説明していきます。

まず、int型変数 a , b を宣言し、それぞれに 10 , 15 を代入します。

それを printf を用いて出力すると、「aの値は10 , bの値は15」と出力されます。

次に plus 関数を用いて、a のアドレス &a b のアドレス &b を引数として渡します。

下に飛んで、関数内では、仮引数として受け取った *x (aのアドレスにある値、つまり10)
*y(bのアドレスにある値、つまり15)に対して、5を足すというプログラムになっています。

「*x += 5」というのは「*x = *x + 5」と等しいです。

このような関数を用いることで、「return」を使わずして、値を変えることができ、さらに複数の変数も変更することができるのです。

そのあとの printf をみてみると、「aの値は15 , bの値は20」としっかり出力されていることがわかります。

このようにして、「2つの値を変更する関数」を作ることができるのです。

最後に

最後まで解説を見ていただきありがとうございます!

ポインタの説明って難しいんですね(笑)

ポインタには今回紹介した使い方以外にもたくさんの使い方があります。

最初はこんなの必要あるのか?と思うかもしれませんが、プログラムが大きくなればなるほどポインタを使うか使わないかで大きな差になってきます。

ぜひこれからも勉強を続けて、ポインタ、そしてC言語への理解を深めていってください。

今回の解説が困っていた人の参考になればうれしいです!