• 検索結果がありません。

基礎プログラミング2015

N/A
N/A
Protected

Academic year: 2021

シェア "基礎プログラミング2015"

Copied!
17
0
0

読み込み中.... (全文を見る)

全文

(1)

応用プログラミング

第11回

関数の名前

(2)
(3)

今日の内容

(1) 関数宣言:関数の戻り値の型, 名前, 引数の型のみ先行指定 (2) 多重定義:引数が異なる同じ名前の関数の作成 (3) デフォルト引数:関数の仮引数にデフォルトで引数を指定 (4) 関数テンプレート:様々な型に対応できる関数の作成 *これまでの関数  必ずmain関数(呼び出し元)の前に関数定義をする  宣言した仮引数の数と実引数として渡す値の数は同じ  仮引数の型に合わせた値渡し

(4)

関数宣言(P.109)

*最初に関数の戻り値の型・関数名・仮引数の型のみ宣言する  これにより, main関数後に関数定義ができる

void print(const int [], int); int main(){

const int asize = 5;

int array[asize] = {1, 2, 3, 4, 5}; print(array, asize);

return 0; }

void print(const int x[], int size){

for(int i = 0; i < size; i++){ cout << x[i] << ‘ ’; } cout << endl; } 先に宣言だけ(関数宣言) 引数の変数名は要らない (書いても無視される) main関数の後に作成可能 このときは普通の関数の作成と 同様に行えば良い(関数定義)

(5)

関数宣言(P.110)

*関数宣言では「戻り値の型, 関数名, 引数の型と個数」が決まる void print(const int [], int);

*上の関数宣言に対し, 以下の関数定義は全てエラー void print(const double x[], int size){…}

void print(const int x[], int size, int n){…} int print(const int x[], int size){…}

void output(const int x[], int size){…}

引数の型が異なる 引数の数が異なる 返却値型が異なる

(6)

関数名の多重定義(オーバーロード)(P.110-112)

*全く同じ機能の関数に, 引数の型の違いだけで別名をつけるのは 関数の名前が増え, プログラムが分かりにくくなる

void swap(int& x, int& y);

void swapd(double& x, double& y); void swapch(char& x, char& y);

*多重定義:引数が異なれば, 関数に同じ名前をつけることが可能

 同じ機能ならば同じ関数名を付けておく方が可読性が上がる void swap(int& x, int& y);

void swap(double& x, double& y); void swap(char& x, char& y);

(7)

関数名の多重定義(オーバーロード)(P.110-112)

*返却値型のみが違う同名の関数は定義できない

void swap(int& x, int& y);

int swap(int& x, int& y);

void swap(int& x, int& y);

int swap(double& x, int& y);

*引数が1個でも異なれば返却値型は違ってもOK

void input(int& x);

void input(int x[], int size);

(8)

関数名の多重定義(オーバーロード)(P.110-112)

*引数の型が違うだけの同名関数でも, それぞれの関数定義の

中身は異なることに注意する.

void swap(int& x, int& y){

int tmp = x; x = y;

y = tmp; }

void swap(double& x, double& y){

double tmp = x; x = y;

y = tmp; }

(9)

デフォルト引数(P.113)

*2~4個の整数値の加算を関数で行いたい

int sum(int, int, int =0, int =0); int main(){

cout << sum(1, 2, 3, 4) << endl; cout << sum(1, 2, 3) << endl; cout << sum(1, 2) << endl; }

int sum(int x, int y, int z, int w){ return x+y+z+w; }  個数に合わして一つずつ作る ・・・ 煩雑!  一つの関数でどの個数でも対応できないか? ・・・ デフォルト引数 *実引数が3個しかない場合 → 4個目の引数を0としてsumを呼ぶ *実引数が2個しかない場合 → 3, 4個目の引数を0としてsumを呼ぶ sum(1, 2, 3, 4) → 10 sum(1, 2, 3) → 6 sum(1, 2) → 3 関数では4つの値の和 x+y+z+wを返す

(10)

デフォルト引数(P.113)

*途中の引数のみにデフォルトの値を設定することはできない int sum(int x, int y=0, int z, int w);

*デフォルトの値は必ず後ろから順に設定する int sum(int x, int y=1, int z=2, int w=3);

*全ての引数にデフォルトの値を設定することも可能 int sum(int x=0, int y=0, int z=0, int w=0); *関数宣言をする場合は, 関数宣言のときに,

関数定義のみの場合は, 関数定義のときに デフォルト引数の宣言を行う.

(11)

関数テンプレート(P.114)

void swap(int& x, int& y){ … }

void swap(double& x, double& y){ … }

void swap(char& x, char& y){ … }

void swap(string& x, string& y){ … }

*全く同じ処理を行える様々な型に対応した関数を作成したい  多重定義で全ての型の分を用意する ・・・ 膨大な関数の数

 関数テンプレートを用いる

template < class T >

(12)

関数テンプレート(P.114)

template < class T > // T:テンプレート仮引数  この前置きの後にTを含めて宣言されるのが 関数テンプレートと呼ばれる“関数の枠組み” <イメージ> template < class T > T sum(T x, T y, T z){ … } *枠組みの用意(非実体)

int sum(int x, int y){ … }

*int用に具現化された

テンプレート関数(実体)

double sum(double x, double y){ … }

*double用に具現化された テンプレート関数(実体) int型の実引数を 受け取ると… double型の実引数 を受け取ると…

(13)

関数テンプレート(P.114)

template < class Type >

void print(Type x[], int size){ for(int i = 0; i < size; i++){

cout << x[i] << “ ”; }

cout << endl; }

int main(){

const int size = 3;

int a[size] = {1, 2, 3};

double d[size] = {1.0, 2.1, 3.0}; char c[size] = {‘a’, ‘b’, ‘c’}; print(a, size);

print(d, size); print(c, size); return 0;

} void print(int x[], int size){ … }

void print(double x[], int size){ … } void print(char x[], int size){ … }

// 実行結果 1 2 3

1.0 2.1 3.0 a b c

(14)

関数テンプレートライブラリ(P.115)

*<algorithm>ヘッダファイルには便利な関数テンプレートがある 1. template <class T> const T& min(const T& a, const T& b)  a と b の小さい方を返す関数

2. template <class T> const T& max(const T& a, const T& b)  a と b の大きい方を返す関数

3. template <class T> void swap(T& a, T& b)  a と b を入れ替える関数

*これらは関数テンプレートなので, 変数型は気にせず使用可能  各ヘッダファイル内に準備されている関数については以下参照  http://cpprefjp.github.io/reference.html

(15)

関数名に関する注意事項(P.116)

*コンパイラが関数呼び出しで対応する関数を見つけるためには 「引数の数, 引数の型, 戻り値」を調べる

# もし型などが異なったとしても, すぐにエラーにはならず, 以下を試行  格上げ:boolをintに, intをdoubleに, 等のデータ型の格上げ

 標準変換:intとdoubleの相互変換, intとunsigned intの変換等  ユーザによって定義された型変換(キャスト)

 引数の個数が不定の関数を調査(デフォルト引数などによる) *これらのせいでエラーになる可能性があるので,

(16)

関数名に関する注意事項(P.116)

多重定義, デフォルト引数, 関数テンプレートの利用指針 template関数の関数宣言 *基本的には, 関数には別名をつける  多重定義 ・・・ 関数の処理方法, 引数, 型が違うが処理内容は同じ  デフォルト引数 ・・・ 引数の個数のみが異なる場合のみ  関数テンプレート ・・・ 引数の型のみが異なる場合のみ  template宣言も同時に行う  関数定義の方でも(改めて)template宣言は行う

(17)

練習問題

問題. 5個の整数と実数を別々に入力すると, その中で一番大きい 値を出力する以下のプログラムを完成させよ. #include<iostream> // ここにMax関数の関数定義 int main(){ const int N = 5; int x[N] = {}, i = 0; cout << “整数を入力:”;

while(i < N && cin >> x[i]) i++; Max(x, N);

double y[N] = {};

cout << “実数を入力:”; i = 0; while(i < N && cin >> y[i]) i++; Max(y, N); return 0; } // 実行例 整数を入力: 1 5 7 9 3 一番大きい値: 9 実数を入力: 1.2 4.9 5.1 3.8 2.4 一番大きい値: 5.1

参照

関連したドキュメント

Oracle WebLogic Server の脆弱性 CVE-2019-2725 に関する注 意喚起 ISC BIND 9 に対する複数の脆弱性に関する注意喚起 Confluence Server および Confluence

分配関数に関する古典統計力学の近似 注: ややまどろっこしいが、基本的な考え方は、q-p 空間において、 ①エネルギー En を取る量子状態

例えば、総トン数 499 トン・積載トン数 1600 トン主機関 1471kW(2000PS)の内航貨 物船では、燃料油の加熱に使用される電力は

「特殊用塩特定販売業者」となった者は、税関長に対し、塩の種類別の受入数量、販売数

いてもらう権利﹂に関するものである︒また︑多数意見は本件の争点を歪曲した︒というのは︑第一に︑多数意見は

3 学位の授与に関する事項 4 教育及び研究に関する事項 5 学部学科課程に関する事項 6 学生の入学及び卒業に関する事項 7

 本資料は、宮城県に所在する税関官署で輸出通関又は輸入通関された貨物を、品目別・地域(国)別に、数量・金額等を集計して作成したもので

本資料は、宮城県に所在する税関官署で輸出通関又は輸入通関された貨物を、品目別・地域(国)別に、数量・金額等を集計して作成したもので