【自主学習】ひたすらコードで覚えるC++［#3］

# はじめに
今回は3回目ということで、関数やポインタについて学んでいきたいと思います。


# 使用する環境
環境はVisual Studio 2022を使用します。

# 関数を定義する
関数が呼び出されると、引数の値が渡されて処理されます。```buy(num);```という一行だけでbuy関数の処理が行われます。

```diff_c
#include <iostream>
using namespace std;

//buy関数の定義
void buy(int x)
{
	cout << x << "円分買い物をしました。\n";
}

//buy関数の呼び出し
int main()
{
	int num;

	cout << "本日はいくら買い物をしましたか？\n";

	cin >> num;

	buy(num);

    return 0;

}
```

# 戻り値をつかう
関数の呼び出し元に特定の情報を返すことができます。このプログラムでは足し算の結果```z```を```return```で返しています。

```diff_c
#include <iostream>
using namespace std;

//buy関数の定義
int buy(int x, int y)
{
	int z;

	cout << x << "円分の買い物と" << y << "円分の買い物をしました。\n";

	z = x + y;

	return z;
}

//buy関数の呼び出し
int main()
{
	int num1, num2, sum;

	cout << "1つ目のお店でいくら買い物をしましたか？\n";

	cin >> num1;

	cout << "2つ目のお店でいくら買い物をしましたか？\n";

	cin >> num2;

	sum =buy(num1, num2);

	cout << "合計で" << sum << "円です。\n";

	return 0;

}
```
# インライン関数
関数を使うコードでは処理を実行するのに時間がかかる場合があります。そのため、インライン関数をつかうことでプログラムの処理速度が向上する場合があります。

```diff_c
#include <iostream>
using namespace std;

//max関数の定義
inline int max(int x, int y) { if (x > y) return x; else return y; }

//buy関数の呼び出し
int main()
{
	int num1, num2, sum;

	cout << "1つ目のお店でいくら買い物をしましたか？\n";

	cin >> num1;

	cout << "2つ目のお店でいくら買い物をしましたか？\n";

	cin >> num2;

	sum =max(num1, num2);

	cout << "大きな買い物は" << sum << "円の買い物をしたお店です。\n";

	return 0;

}
```
# 関数プロトタイプ宣言とデフォルト引数
関数の呼び出しを関数の定義よりも前に記述する場合は、関数プロトタイプ宣言が必要になります。またデフォルト引数を設定しておくこと（ここでは```x = 1000```）で引数を指定しなくても呼び出すことができます。


```diff_c
#include <iostream>
using namespace std;

//buy関数の定義
void buy(int x = 1000);

//buy関数の呼び出し
int main()
{
	cout << "1つ目のお店でいくら買い物をしますか？\n";

	buy(3000);

	cout << "2つ目のお店ではデフォルト金額で買い物をします。\n";

	buy();

	return 0;

}

//buy関数の定義
void buy(int x)
{
	cout << x << "円\n";
}
```

# 関数のオーバーロード
似たような複数の処理をオーバーロード（多重定義）することで、同じ関数名で異なる引数の型・個数をもつ関数を定義できます。

```diff_c
#include <iostream>
using namespace std;

//max関数の定義
int max(int x, int y);
double max(double x, double y);

//buy関数の呼び出し
int main()
{
	int a, b;
	double da, db;

	cout << "2つの整数を入力してください。\n";
	cin >> a >> b;

	cout << "2つの小数を入力してください。\n";
	cin >> da >> db;

	int ans1 = max(a, b);
	double ans2 = max(da, db);

	cout << "整数値の最大値は" << ans1 << "です\n";
	cout << "小数値の最大値は" << ans2 << "です\n";

	return 0;

}

//max(int型)関数の定義
int max(int x, int y)
{
	if (x > y)
		return x;
	else
		return y;
}

//max(double型)関数の定義
double max(double x, double y)
{
	if (x > y)
		return x;
	else
		return y;
}
```

# 関数テンプレートをつかう
関数テンプレートを使うことで、指定した型に置き換えた関数を作成することができます。
状況によって関数のオーバーロードと関数テンプレートを使い分けるのが効果的です。

```diff_c
#include <iostream>
using namespace std;

//関数テンプレート
template <class T>
T maxt(T x, T y) {
	if (x > y)
		return x;
	else
		return y;
}

//関数テンプレートを呼び出す
int main()
{
	int a, b;
	double da, db;

	cout << "2つの整数を入力してください。\n";
	cin >> a >> b;

	cout << "2つの小数を入力してください。\n";
	cin >> da >> db;

	int ans1 = maxt(a, b);
	double ans2 = maxt(da, db);

	cout << "整数値の最大値は" << ans1 << "です\n";
	cout << "小数値の最大値は" << ans2 << "です\n";

	return 0;

}
```

# アドレスを知る
アドレス演算子```&```を使ってアドレスの値を見ることができます。C++のアドレスはコンピュータ内の住所のようなもので、16進数の数値などをつかって表すことが多いです。

```diff_c
#include <iostream>
using namespace std;

int main()
{
	int a;

	a = 10;

	cout << "aの値は" << a << "です\n";
	cout << "変数aのアドレスは" << &a << "です\n";

	return 0;
}
```

# ポインタから変数の値を知る
ポインタに変数のアドレスを格納することで、ポインタから逆にたどって元の変数の値を知ることができます。

```diff_c
#include <iostream>
using namespace std;

int main()
{
	int a;
	int* pA;

	a = 10;
	pA = &a;

	cout << "aの値は" << a << "です\n";
	cout << "変数aのアドレスは" << &a << "です\n";
	cout << "ポインタpAの値は" << pA << "です\n";
	cout << "pAの値は" << *pA << "です\n";

	return 0;
}
```

# 関数の引数にポイントをつかう
原則として、関数内で実引数を変更することはできませんが、ポイントを使うことで、関数内で実引数側を変更することができます。

```diff_c
#include <iostream>
using namespace std;

//swap関数の宣言
void swap(int* pX, int* pY);

int main()
{
	int num1 = 10;
	int num2 = 20;

	cout << "変数num1の値は" << num1 << "です\n";
	cout << "変数num2の値は" << num2 << "です\n";
	cout << "変数num1とnum2の値を交換します。\n";

	swap(&num1, &num2);

	cout << "変数num1の値は" << num1 << "です\n";
	cout << "変数num1の値は" << num2 << "です\n";

	return 0;
}

//swap関数の定義
void swap(int* pX, int* pY)
{
	int tmp;

	tmp = *pX;
	*pX = *pY;
	*pY = tmp;
}
```

# 関数の引数に参照をつかう
参照を使うことで、仮引数を変更すると実引数の値を変更することができます。

```diff_c
#include <iostream>
using namespace std;

//swap関数の宣言
void swap(int& x, int& y);

int main()
{
	int num1 = 10;
	int num2 = 20;

	cout << "変数num1の値は" << num1 << "です\n";
	cout << "変数num2の値は" << num2 << "です\n";
	cout << "変数num1とnum2の値を交換します。\n";

	swap(num1, num2);

	cout << "変数num1の値は" << num1 << "です\n";
	cout << "変数num1の値は" << num2 << "です\n";

	return 0;
}

//swap関数の定義
void swap(int& X, int& Y)
{
	int tmp;

	tmp = X;
	X = Y;
	Y = tmp;
}
```
# さいごに
今回は関数やポイントに関する知識を中心に学んでいきました。
次回からはデータを扱う上で重要な配列について学んでいきます。

# 参考文献

この記事は以下の情報を参考にして執筆しました。
[やさしいC++ 第4版 (「やさしい」シリーズ) ](https://www.amazon.co.jp/%E3%82%84%E3%81%95%E3%81%97%E3%81%84C-%E7%AC%AC4%E7%89%88-%E3%80%8C%E3%82%84%E3%81%95%E3%81%97%E3%81%84%E3%80%8D%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E9%AB%98%E6%A9%8B-%E9%BA%BB%E5%A5%88/dp/4797370998)