【C++入門講座】関数を扱えるようになろう!

スポンサーリンク
初心者C++
スポンサーリンク

はじめに

関数さえ作れるようになってしまえば、プログラミングちょこっとできるよ!と言えるようになるのではないでしょうか?

それくらいに関数が作れるだけで、コードは簡潔になり、できる事が増えるという事です!

今回はしっかりと読み進めて基礎を完璧にしていただきたいと思います!

関数とは?

関数とは、紙に書かれたプログラムを保存するバインダーのようなもので、呼び出す事で何度でもバインダーの先頭に書かれたプログラムから順番に実行させる事ができます。

教本などでよく言い換えられるのが自販機で、自販機(関数名)にお金を入れる事(入力)でジュースが出てくる(出力)というような説明をされている事が多いような気がします。

ただし、データを入力する必要がない関数もあれば、出力のない関数もあり例外が多いので、この例えはあまり好きではないです。

かといって上手な例えも思い浮かばなかったので上手な例えは誰か他の人が見つけてくれることを祈りましょう。

関数の定義について

関数の定義は次のようにして行います。

返り値の型 関数名 (引数の型と仮引数の名前,...,引数の型と仮引数の名前){
	プログラム;
	return 返り値;//これについては条件分岐先にあっても良く,複数あっても良い.ただし,この文がある場所で関数の実行は終了となる.
}

関数を定義するにあたって「引数」と「返り値」がとても大切な要素となっています。

これらについて順に説明していきます。

引数ってなに?

引数とは関数が呼び出された時に、呼び出し元から関数へと受け渡すデータのことです。

この引数は、予め受け取るデータのデータ型と、順番を決めておく必要があり、決められた通りでないとエラーが出ます。

ここで引数には実引数と仮引数の二種類があり、次のような違いがあります。

  • 実引数:関数を呼び出す時に、受け渡す実際のデータのこと。要するに呼び出し元で使っているデータのこと。
  • 仮引数:関数が呼び出された際に、受け渡されたデータをコピーしたもののこと。関数内でしか使えず、呼び出し元のデータには影響を与えないデータのこと。

関数内では仮引数を扱いますが、この仮引数の名前も関数を定義する時に決める必要があります。

また、引数は関数にとって必ずしも必要なものではなく、引数なしの関数を定義することもできます。

返り値ってなに?

返り値とは呼び出された関数の処理が終わった後に、呼び出し元に受け渡すデータのことです。

簡単に言うと、関数を呼び出した結果として呼び出した場所に残る値のことです。

また、関数を定義する際に返り値のデータ型を必要としますが、返り値をなしとする場合には「void型」を用いて宣言します。

「return 返り値;」というのが呼び出し元に値を返すという意味を持っています。

返り値は関数の処理が終わった後に、呼び出し元に受け渡すものなので逆に言えば、この文があるところが関数の処理が終わる場所となります。

そのため、条件分岐の中に置くこともできます。

実際に定義してみよう!

例として、いくつかの関数を以下に示します。

例1:「int型の引数を二つ受け取り、二つの加算結果をint型で返す関数」

int func1(int a, int b){

	return a+b;
}

例2:「int型の引数を二つ受け取り、二つの乗算結果を表示し、返り値はない関数」

void func2(int a, int b){

	std::cout << a*b << std::endl;
}

例3:「引数はなく、標準入力を行い、結果として得たint型の値を返す関数」

int func3(){

	int a;
	std::cin >> a;
	
	return a;
}

例4:「引数と返り値はなく、HelloWorld!と表示する関数」

void func4(){

	std::cout << "HelloWorld!" << std::endl;
}

関数の呼び出しについて

関数の呼び出しは次のようにして行います。

関数名(実引数,...,実引数)

実引数については定義する時に決めた引数のデータ型、順番の通りに受け渡す必要があるので注意してください。

また、呼び出す関数は呼び出す場所よりも前に定義されている必要があります。

例として先ほどの関数を使ったプログラムを次に示します。

#include<iostream>

int func1(int a, int b){ //int型の引数a,b

	return a+b; //int型の返り値a+b
}

void func2(int a, int b){ //int型の引数a,b //返り値なし

	std::cout << a*b << std::endl;
}

int func3(){ //引数なし

	int a;
	std::cin >> a;
	
	return a; //int型の返り値a
}

void func4(){ //引数,返り値なし

	std::cout << "HelloWorld!" << std::endl;
}

int main(){

	func4(); //呼び出し

	int x,y;
	
	x = func3(); //呼び出し,返り値をxに格納
	y = func3(); //呼び出し,返り値をyに格納
	
	std::cout << func1(x,y) << std::endl; //呼び出し,実引数x,yを与える
	
	func2(x,y); //呼び出し,実引数x,yを与える
	
	return 0;
}

グローバル変数とローカル変数について

関数を使ってプログラムを書いていく上で、変数の扱い方には気をつける必要があります。

最後にグローバル変数とローカル変数の違いと、使い分けについて説明します。

グローバル変数とは?

別名を大域変数といい、プログラムのどの部分からでも参照することのできる変数です。

また、一つのプログラムにおいて同じ名前のグローバル変数を宣言することができません。

具体的には、次プログラム中の変数「global」のように、関数の外側に書かれる変数のことを指します。

#include<iostream>

int global;

int main(){
	
	return 0;
}

ローカル変数とは?

別名を局所変数といい、プログラムの中の一部でのみ参照することができる変数です。

また、別々の関数の中であれば、同じ名前の変数を宣言することができます。

具体的には、次のプログラム中の変数「local」のように、関数の中に書かれる変数のことを指します。

#include<iostream>

int main(){
	
	int local;
	
	return 0;
}

使い分けについて

何が正解というものがあるわけではありませんが

「できるだけローカル変数を使う」

というのが基本だと思います。

ネットで調べると、実行速度、メモリ云々とか難しい話がたくさん出てきます。

でも、何言ってるかわからないと思うので、大掛かりなプログラムを作るとかでもない限り、気にしなくていいです。

とりあえず、ローカル変数で大丈夫な時はローカル変数を使うようにしましょう!

演習問題

最後に演習問題です。

そろそろ大掛かりなこともできると思いますが、基本的で簡単な問題のみしか出しません。

サクッと解いて理解していることを確認しましょう!

演習問題1

次の条件を満たすプログラムを作成せよ。

  • 二つの整数値を受け取り、大きい方を返り値とする関数「large」を定義
  • 整数値と文字を受け取り、整数値の数だけ文字を出力する関数「print」を定義
  • メイン関数で標準入力から二つの整数値と文字を入力させ、largeとprintを用いて、大きな整数値の数だけ文字を表示して終了

ヒント:return文は条件分岐の中に置くこともできます。

演習問題2

次の条件を満たすプログラムを作成せよ。

  • グローバル変数「total」を宣言する
  • 一つの整数値を受け取り、グローバル変数「total」に加算する関数「add」を定義
  • 加算した合計の値と、平均を表示する関数「print」を定義
  • 標準入力から「0」以下の整数値が入力されるまでaddを用いて入力された整数値を加算し、「0」以下が入力された場合printを呼び出して終了

ヒント:平均を出すには加算した回数が必要です。

演習問題1解答

いくつかの解答があると思われるが、解答例として以下のプログラムを用意した。

#include<iostream>

int large(int a,int b){
	
	if(a > b){ //条件分岐させて返り値を決める
		return a;
	}
	return b;
}

void print(int a, char b){

	for(int i = 0; i < a; i++){
		std::cout << b << std::endl;
	}
}

int main(){
	
	int a,b;
	char c;
	
	std::cout << "整数値二つと文字を一つ入力してください(ex:1 2 a)" << std::endl;
	std::cin >> a >> b >> c;
	
	print(large(a,b),c); //largeの引数にa,bを.printの引数にlarge(a,b)の返り値とcを与える
	
	return 0;
}

演習問題2解答

いくつかの解答があると思われるが、解答例として以下のプログラムを用意した。

#include<iostream>

int total,times; //グローバル変数total,timesの宣言 timesで加算回数を計測

void add(int a){
	
	total += a; //totalに引数で受け取った整数値を加える
	times++; //加算を行うたびに1加える
}

void print(){
	
	std::cout << "合計値は" << total << std::endl; //出力
	std::cout << "平均値は" << total/times << std::endl; //合計値を加算回数で割ったものを出力
}

int main(){
	
	while(1){
		
		int a;
		std::cin >> a;
		
		if(a <= 0){
			break;
		}else{
			add(a); //関数の呼び出し,aを引数として渡す
		}
	}
	
	print(); //関数の呼び出し

	return 0;
}

コメント

タイトルとURLをコピーしました