【C言語入門】ポインタのわかりやすい使い方(配列、関数、構造体)

こんにちは!フリーランスの長野です。

ポインタって使ってますか?

ポインタの使い方を理解するのは最初はなかなか難しいかもしれません。C言語を学習する上では、どうしても手が止まってしまう部分です。

しかし、ポインタを使ってやっていることはアドレスかアドレス先の値を操作するかどちらかに限られます。これを変数や配列、関数、構造体に対して適用して使っています。

配列、関数、構造体のようにひとかたまりにしたものを、ポインタを使うことでひとかたまりのまま扱うことができるので便利です。配列の要素を一つずつ扱ったり、構造体のメンバを一つずつ扱う手間を省くことができます。

ですのでポインタを使いこなせるようになると、記述の手間を省きつつもできることが増えます。

この記事では、ポインタについて

  • ポインタとは
  • ポインタを使うメリットとは
  • ポインタの使い方について
  • アドレスの使い方について
  • ポインタの演算について
  • ポインタのポインタについて
  • 配列でのポインタについて
  • 関数でのポインタについて
  • 構造体でのポインタについて


など基本的な内容から、具体的な使い方の内容についても解説していきます。

今回はポインタについて、使い方をわかりやすく解説します!

ポインタ、アドレスとは

ポインタとは、変数のアドレスを記憶する変数のことです。

アドレスとはメモリ上に与えられた番号のことです。変数を宣言すると、その変数にアドレスすなわちメモリ上の番号が与えられます。

アドレスにアクセスすることで変数の値を取得することができます。アドレスはデフォルトでは16進数で表されます。また、ポインタ変数は整数の加減算ができます。

メモリ上の番号の演算やアドレス先の値を取得する際に使用します。

ポインタを使うメリットとは

ポインタを使うメリットについてはいくつか挙げられます。

  • ポインタを使うことで、アドレス先の値を取得したり、変更することができる。
    特に関数の引数でポインタを使って参照渡しを行うと、複数の変数を1つの関数で処理変更できる。
  • ひとつのポインタ変数で、配列のすべての要素の値を取得したり、変更することができる。
    したがって、配列の要素を一つずつ扱う手間が省ける。
  • ひとつのポインタ変数で、構造体のすべてのメンバの値を取得したり、変更することができる。
    したがって、構造体のメンバを一つずつ扱う手間が省ける。
  • ひとつのポインタ変数で、複数の関数から使う関数を選択できる。
    したがって、後からでも簡単に処理内容を変更することができる。


などが挙げられます。

それぞれのメリットについては、これから詳しく解説していきます。

ポインタの使い方について

ポインタの使い方について説明していきます。

ポインタの使い方について

まずはポインタの使い方について説明します。

ポインタ変数は変数名の前に「*」(アスタリスク)を付けて宣言します。ポインタ変数には変数のアドレスを代入します。

変数のアドレスは変数名の前に「&」(アンパサンド)を付けて表します。変数とポインタ変数は同じ型である必要があります。

それではサンプルコードで確認していきましょう。

実行結果:

このサンプルコードでは、int型のポインタ変数「p_num」を宣言しています。

ポインタ変数「p_num」に同じint型の変数「num」のアドレス「&num」を代入しています。ポインタ変数をprintf関数で出力表示する際にアドレスを表示するために「%p」変換子を使用しています。

アドレスの使い方について

次にアドレスの使い方について説明します。

変数のアドレスは変数名の前に「&」(アンパサンド)を付けて表します。変数のアドレスがポインタ変数の値となります。変数のアドレスの前に「*」(アスタリスク)を付けるとアドレス先の値を取得することができます。

それではサンプルコードで確認していきましょう。

実行結果:

このサンプルコードではint型変数「num」のアドレス「&num」をprintf関数を使って出力表示しています。アドレス「&num」の前に「*」(アスタリスク)を付けアドレス先の値を取得表示しています。

またアドレス「&num」を代入したポインタ変数「p_num」の前に「*」(アスタリスク)を付けても、同様にアドレス先の値を取得表示していることがわかります。

ポインタの演算について

ポインタの演算について説明します。

配列の要素はメモリ上の番号つまりアドレスが連続していますので配列の要素を操作する場合にポインタの演算を使用すると便利です。

実行結果:

このサンプルコードではchar型、int型、float型、double型、それぞれの配列のポインタの演算結果と配列の要素を比較しています。

いずれの配列においても、ポインタ変数の値は配列の先頭のアドレスと一致しています。ポインタ変数の値に1加算すると配列の次の要素のアドレスと一致しています。

char型の配列はポインタ変数の値を1加算するとアドレスの値も1増えています。英文字1文字では1バイト(アドレス1個分)使用していることがわかります。

int型の配列はポインタ変数の値を1加算するとアドレスの値は4増えています。int型の変数1個では4バイト(アドレス4個分)使用していることがわかります。

float型の配列はポインタ変数の値を1加算するとアドレスの値は4増えています。float型の変数1個では4バイト(アドレス4個分)使用していることがわかります。

double型の配列はポインタ変数の値を1加算するとアドレスの値は8増えています。double型の変数1個では8バイト(アドレス8個分)使用していることがわかります。

ポインタのポインタについて

ポインタとは、変数のアドレスを記憶する変数のことでした。

ポインタもある種の変数です。

ということは、ポインタという変数のアドレスもメモリのどこかに存在し、アドレス番号が付けられています

ですので、ポインタにポインタのアドレスを格納することも可能です。これをポインタのポインタと言います。

ポインタのポインタを宣言するには、さらに「*」(アスタリスク)を付けます。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、int型の変数numのアドレスを格納するポインタ変数p_numをまず宣言、定義しています。

このポインタ変数p_numのアドレスを格納するために、ポインタ変数のポインタpp_numを次に宣言、定義しています。

配列でのポインタの使い方

配列でのポインタの使い方についてみていきましょう。

アドレスアクセスについて

配列の要素の値を取得する際にポインタを使ってアドレスから取得する方法があります。

使い方についてはこちらのサイトで詳しく解説していますので参考にしてくださいね!

【C言語入門】配列の使い方まとめ(初期化、代入、宣言、コピー)
更新日 : 2019年4月22日

2次元配列のポインタのポインタの使い方について

ポインタのポインタを使うことで2次元配列の要素の値を取得する方法があります。

使い方についてはこちらのサイトで詳しく解説していますので参考にしてくださいね!

【C言語入門】2次元配列の使い方まとめ
更新日 : 2019年4月22日

関数でのポインタの使い方

関数でのポインタの使い方について説明します。

引数での参照渡しの使い方

引数にポインタを利用すると値を参照渡しすることができて、2つ以上の複数の変数を処理することができます。

使い方についてはこちらで詳しく解説していますので参考にしてくださいね!

【C言語入門】関数の作り方、呼び出し方(宣言、引数、戻り値)
更新日 : 2019年4月24日

関数ポインタの使い方について

関数ポインタの使い方について説明します。

関数ポインタは関数が格納されたメモリアドレスを取得します。関数を呼び出す際に関数ポインタの内容を別の関数のアドレスに変更することで、呼び出す関数を変更することができます。

つまり、呼び出す関数を動的に変更することができます。ただし、引数の型と引数の数はそろえる必要があります。

「typedef」句を使って関数ポインタの型を宣言すると記述が簡潔になります。

この関数ポインタ型名のオブジェクトを生成して使用します。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードではcalc型の関数ポインタを宣言しています。これを「c」と定義してオブジェクトを生成し使用しています。

オブジェクト「c」に「sum」関数のアドレスを代入すると足し算が実行され、「mul」関数のアドレスを代入すると掛け算が実行されています。

このように関数ポインタを使うと処理内容を意図的に変えることができるので便利です。

構造体でのポインタの使い方

構造体でのポインタの使い方について説明します。

実体のポインタの使い方

実体にポインタを使うとすべてのメンバを含めた実体全体を操作することができるので便利です。

使い方についてはこちらで詳しく解説していますので参考にしてくださいね!

【C言語入門】構造体の使い方(struct、ポインタ、アロー演算子)
更新日 : 2019年4月20日

アロー演算子の使い方について

アロー演算子は構造体の実体のポインタからメンバを呼び出す際に使用します。

「->」記号を使います。

下記のように記述して使用します。

サンプルコードで確認していきましょう。

実行結果:

このサンプルコードでは、strct型の構造体を宣言しています。

strct型ポインタ変数にstrct型構造体のアドレスを代入しています。ポインタ変数からアロー演算子を使用して構造体のメンバを呼び出し値を代入しています。

strct型構造体の実体からメンバを呼び出し出力表示しています。

まとめ

ここでは、ポインタについて説明しました。

ポインタを使うとアドレス先から値を操作することができます。そうすることで配列、関数、構造体など複雑な構成を簡単な記述で扱うことができます。

ポインタはたくさんの用途で使えて便利ですので使いこなすことができるように、この記事を何度も参考にして下さいね!

LINEで送る
Pocket

最短でエンジニアを目指すなら侍エンジニア塾

cta_under_bnr

侍エンジニア塾は業界で初めてマンツーマンレッスンを始めたプログラミングスクールです。これまでの指導実績は16,000名を超え、未経験から数多くのエンジニアを輩出しています。

あなたの目的に合わせてカリキュラムを作成し、現役エンジニア講師が専属であなたの学習をサポートするため効率よく学習を進めることができますよ。

無理な勧誘などは一切ありません。まずは無料体験レッスンを受講ください。

無料体験レッスンの詳細はこちら

書いた人

長野 透

長野 透

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
[email protected]

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説