はじめに
C++やC言語で、ある関数の中で構造体のデータを使いたい場合、どのようにして関数にそのデータを渡せばよいでしょうか?一つの方法は構造体全体をコピーして渡す「値渡し」ですが、構造体が大きい場合、コピーのコストが無視できなくなります。
より効率的で一般的な方法が、「ポインタ渡し」です。これは、構造体の実体をコピーするのではなく、その構造体が格納されているメモリアドレスだけを関数に教える方法です。これにより、プログラムのパフォーマンスが向上し、関数内で元の構造体の値を直接変更することも可能になります。
この記事では、関数の引数として構造体を指すポインタを渡し、関数内でそのデータを利用する基本的な方法を解説します。
構造体をポインタで渡すサンプルコード
このコードは、Book
(本)の情報を表示するための displayBook
という関数を定義します。main
関数は Book
型の変数を作成し、そのアドレスを displayBook
関数に渡します。
完成コード
#include <iostream>
#include <string>
// 「本」構造体の定義
struct Book {
std::string title; // タイトル
std::string author; // 著者
int price; // 価格
};
// --- 1. 関数のプロトタイプ宣言 ---
// 引数として、Book構造体を指すポインタ(*p_book)を受け取る
void displayBook(const Book* p_book);
int main() {
// --- 2. 構造体の変数(実体)を作成 ---
Book myBook;
myBook.title = "C++プログラミング入門";
myBook.author = "山田 太郎";
myBook.price = 2800;
// --- 3. 関数の呼び出し時に、アドレス演算子(&)で変数のアドレスを渡す ---
displayBook(&myBook);
return 0;
}
// --- 関数の本体(定義) ---
void displayBook(const Book* p_book) {
std::cout << "--- 書籍情報 ---" << std::endl;
// --- 4. アロー演算子(->)でポインタ経由でメンバにアクセス ---
std::cout << "タイトル: " << p_book->title << std::endl;
std::cout << "著者: " << p_book->author << std::endl;
std::cout << "価格: " << p_book->price << "円" << std::endl;
}
コードの解説
1. void displayBook(const Book* p_book);
これは、displayBook
関数のプロトタイプ宣言です。main
関数より後に関数の本体を記述する場合、main
関数が displayBook
の存在を知るために、この宣言が必要になります。
Book* p_book
: この関数の引数p_book
が、「Book
型の構造体を指すポインタ」であることを示しています。const
:const
を付けることで、この関数の中ではポインタ経由で元の構造体の値を変更できなくなり、より安全なコードになります(今回は表示するだけなのでconst
を付けています)。
2. displayBook(&myBook);
main
関数から displayBook
関数を呼び出している部分です。
&myBook
: アドレス演算子&
を使って、構造体変数myBook
のメモリアドレスを取得し、それを引数として関数に渡しています。
3. void displayBook(const Book* p_book) { ... }
関数の本体です。main
関数から渡された myBook
のアドレスが、ポインタ変数 p_book
に格納されます。
4. cout << p_book->title << endl;
関数の中で、受け取ったポインタ p_book
を使って、メンバにアクセスしています。ポインタ経由でのアクセスなので、ドット演算子 .
ではなくアロー演算子 ->
を使います。p_book->title
は、p_book
が指し示している先(つまり myBook
)の title
メンバを意味します。
まとめ
今回は、関数に構造体を「ポインタ渡し」で渡す基本的な方法を解説しました。
- 関数の引数を、ポインタ型(例:
Book* p
)で宣言する。 - 関数を呼び出す際には、構造体変数のアドレス(例:
&myBook
)を渡す。 - 関数の中では、アロー演算子
->
を使ってメンバにアクセスする。
このポインタ渡しは、C++やC言語における関数呼び出しの基本であり、特に大きなデータを効率的に扱う上で必須のテクニックです。