PPT

プログラミング論 I
関数
http://www.ns.kogakuin.ac.jp/~ct13140/Prog/
E-1
概要
• 関数の作り方を学ぶ
–①関数名,②引数,③戻り値
– 前期で最も重要な事項
–関数
• 後期で最も重要な事項
– ポインタ
E-2
E-3
①関数名
②引数
③戻り値
E-4
関数の概要 0/3
• 関数とは,“複数の処理をひとまとめにした
もの”.
– 同じ処理/似た処理を 何度も記述するような
場合に便利.
• 関数は“引数”を受け取り,“戻り値”を返す
ことができる.
– 実は,printf() も main() も関数.
E-5
関数の概要 1/3
1 #include <stdio.h>
2 void main(){
3
printf("Hello,");
4
printf("World");
5
printf("!!!!\n");
6
printf("------------\n");
7
printf("Hello,");
8
printf("World");
9
printf("!!!!\n");
10
printf("############\n");
11
printf("Hello,");
12
printf("World");
実
13
printf("!!!!\n");
行
14 }
結
この3行まとめて,
1個のグループに
したい.
Hello,World!!!!
-----------Hello,World!!!!
############
果 Hello,World!!!!
E-6
関数の概要 2/3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
void printHW(){
printf("Hello,");
printf("World");
printf("!!!!\n");
}
プログラムは
main()から始まる.
この3行が1個の
グループになった.
グループ名は
printHW
printHW();で,
printHWグループを
一括して実行できる.
void main(){
printHW();
printf("------------\n");
printHW();
printf("############\n");
printHW();
}
正しくは,グループ
関数を“呼び出す”と言う.
ではなく“関数”と呼ぶ E-7
関数の動作 0/2
①
3 void printHW(){
④
4
printf("Hello,");
5
printf("World");
6
printf("!!!!\n");
7 }
⑤
9 void main(){
③
②
10
printHW();
⑥
11
printf("------------\n");
12
printHW();
13
printf("############\n");
14
printHW();
15 }
E-8
関数の動作 1/2
3 void printHW(){
⑨
4
printf("Hello,");
5
printf("World");
6
printf("!!!!\n");
7 }
⑩
9 void main(){
10
printHW();
⑦ printf("------------\n");
11
⑧
12
printHW();
⑪
13
printf("############\n");
14
printHW();
15 }
E-9
関数の作り方① (関数名)
E-10
関数の作り方
③ 戻り値(後述)
この例では,
“void”である.
①
関数名(後述)
この例では,
“printHW”である.
②
3 void printHW (){
4
printf("Hello,");
5
printf("World");
6
printf("!!!!\n");
7 }
引数(後述)
この例では,
空である.
関数の中身
理解すべきは3点.①関数名,②引数,③戻り値
main() の書き方と同じである.main() も関数である.
E-11
関数の作り方 (例)
#include <stdio.h>
関数名に数字も使用可.
void printHW(){
ただし,数字から
printf("Hello,");
始まる関数名はNG.
printf("World");
例:“10pHW”はNG
printf("!!!!\n");
}
関数の中で
void pHW10(){
int i;
変数を使うことも可能.
for(i=0; i<10; i++){
この変数はpHW10の
printf("Hello,World!\n");
中でしか使えない.
}
これはローカル変数.
}
(後述)
void main(){
printHW();
pHW10();
}
E-12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
void sankaku(){
printf("*\n");
printf("**\n");
printf("***\n");
printf("****\n");
}
void gyaku_sankaku(){
printf("****\n");
printf("***\n");
printf("**\n");
printf("*\n");
}
void main(){
sankaku();
gyaku_sankaku();
sankaku();
sankaku();
gyaku_sankaku();
}
関数の作り方 (例)
この1行で,
sankaku() の
全てが一括して
実行される.
実
行
結
果
*
**
***
****
****
***
**
*
*
**
***
****
*
**
***
****
****
***
**
*
E-13
練習 (い)
printf("Hello,\n");
printf("World!\n");
を行う関数を作成し,
それをmain関数から呼び出すプログラムを
記述せよ.
関数名はpr_hl_wldとせよ.
戻り値の欄はvoid,引数の欄は()とせよ.
E-14
関数の作り方② (引数)
E-16
関数の作り方 (引数)
この部分に,引数について記述する.
この例では引数は なし(空,void).
3 void printHW (){
4
printf("Hello,");
5
printf("World");
6
printf("!!!!\n");
7 }
E-17
関数の作り方 (引数)
• 引数とは,関数に与える情報.
– 関数に情報を与えることが可能.
– 関数では,与えられた情報を使用して処理す
ることが可能.
– “情報”とは,int型の値,double型の値などで
ある.
– 引数は,何個でも用意できる.
– 関数に行くときに値を持っていく
E-18
関数の作り方 (引数)
• 引数を受け取る関数.
戻り値(後述)
この例では,
“void”である.
関数名.
この例では,
“print_int”.
引数.
この例では,int型変数1個.
それを i とする.
厳密には仮引数と言う.
void print_int (int i){
printf("i=%d\n", i);
}
E-19
関数の作り方 (引数)
• 関数に引数を渡す.
void main(){
print_int(3);
}
変数 i が宣言
されており,
i を使用可能.
i = 3 として関数が
始まる.
引数がint型1個なので,
int型1個(この例では3)を
与えて関数呼び出し.
void print_int (int i){
printf("i=%d\n", i);
}
実行結果 i=3
E-20
関数の作り方 (引数)
• 呼び出される関数と,呼出し処理をまとめ
ると,
print_int()を
呼び出すには,
呼び出すよりも前に
print_int()が
宣言(記述)されて
いなくてはならない.
(あるいは,宣言されている
ことが推奨される.
C言語では推奨.
C++では必須.)
ただし,プロトタイプ宣言を
行えばこの限りでない.
#include <stdio.h>
void print_int (int i){
printf("i=%d\n", i);
}
プログラムは,必
ずmain()
から始まる.
void main(){
print_int(3);
}
E-21
関数の作り方 (引数の例)
#include <stdio.h>
void printHW_n(int n){
int i;
printf("Hello,World");
for(i=0; i<n; i++){
printf("!");
} /* n個の ! を表示 */
printf("\n");
}
void main(){
printHW_n(4);
printHW_n(7);
}
for文を使う例
実行結果
Hello,World!!!!
Hello,World!!!!!!!
E-22
関数の作り方 (引数の例)
引数2個の例
引数2個の例.
,(カンマ)で区切る
#include <stdio.h>
void print_sum(int a, int b){
printf("%d + %d = %d\n", a, b, (a+b));
}
void main(){
int x=3, y=7;
print_sum(x,y);
}
実引数に,
変数を使った例.
実行結果
3 + 7 = 10
E-23
関数の作り方 (引数の例)
#include <stdio.h>
void print_nchar(char c, int n){
int i=0;
char型とint型を
for(i=0; i<n; i++){
受け取った例.
char型は「文字」型.
printf("%c", c);
文字1個を表す.
}
printf("\n");
}
引数は,char型と,int型なので,
char型の値と,int型の値を入れて
void main(){
呼び出す
char ch = '*';
int x = 7;
実行結果
print_nchar(ch,x);
*******
}
E-24
関数の作り方③ (戻り値)
E-25
関数の作り方 (戻り値)
この部分に,戻り値について記述する.
この例では引数は なし(空,void).
3 void printHW (){
4
printf("Hello,");
5
printf("World");
6
printf("!!!!\n");
7 }
E-26
関数の作り方 (戻り値)
• 戻り値とは,「関数が呼び出しもとに返す
情報」.
– 関数から,関数の呼び出しもとに情報を返す
ことが可能.
– 戻り値は,関数の終了時に返される.
– “情報”とは,int型の値,double型の値な
どである.
– 戻り値は,最大でも1個.
• void なら,0個.
– 関数から戻るときに値を持って帰る
E-27
関数の作り方 (戻り値)
• 戻り値を返す関数.
戻り値.
この例では,
“int”である.
関数名.
この例では,
“square”.
引数.
この例では,
int型変数1個.
int square(int n){
int sq;
sq = n*n;
printf("%d^2 = %d\n", n, sq);
return sq;
}
E-28
関数の作り方 (戻り値)
• 戻り値を返す関数.
①
引数 5
②n=5
int square(int n){
int sq;
sq = n*n; ③sq=25
printf("%d^2 = %d\n", n, sq);
return sq;
}
④
戻り値 25
void main(){
int s;
s = square(5);
printf("square=%d\n", s);
}
戻り値が"25"なので,
square(5) が
25となる.
よって,
s = 25;
E-29
関数の作り方 (戻り値の例)
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int square(int n){
int sq;
sq = n*n;
printf("%d^2 = %d\n", n, sq);
return sq;
}
void main(){
int s;
s = square(5);
printf("square=%d\n", s);
}
実行結果
5^2 = 25
square=25
E-30
関数の作り方 (戻り値の例)
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
double double_square(double d){
引数がdouble型1個なら,
double sq;
double型の値1個を
sq = d*d;
入れて,呼び出す.
printf("%lf^2 = %lf\n", d, sq);
return sq;
}
実行結果
1.500000^2 = 2.250000
void main(){
square=2.250000
double s;
s = double_square(1.5);
printf("square=%lf\n", s);
}
E-31
関数の作り方 (戻り値の例)
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
double double_square(double d){
戻り値がdouble型なら,
double sq;
double型の値を
sq = d*d;
return する.
printf("%lf^2 = %lf\n", d, sq);
return sq;
}
実行結果
1.500000^2 = 2.250000
void main(){
square=2.250000
double s;
s = double_square(1.5);
printf("square=%lf\n", s);
}
E-32
関数の作り方 (戻り値の例)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
int one(){
return 1;
}
int two(){
return 2;
}
int three(){
return 3;
}
i=1,
void main(){
int i, j, k;
i = one();
j = two();
k = three();
printf("i=%d, j=%d, k=%d\n", i, j, k);
}
実行結果
j=2, k=3
E-33
関数の作り方 (戻り値の例)
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int one(){
return 1;
}
int two(){
return 2;
}
int three(){
実行結果
return 3;
}
i=1, j=2, k=3
void main(){
printf("i=%d, j=%d, k=%d\n", one(), two(), three());
}
printf()の中に直接記述してもOK.
one() が"1",two()が"2"と思えば良い.
E-34
関数の作り方 (戻り値がない例)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
void one(){
printf("1\n");
}
void two(){
printf("2\n");
}
void three(){
printf("3\n");
}
void main(){
int i, j, k;
one();
two();
three();
}
実行結果
1
2
3
E-35
関数の作り方 (まとめ)
戻り値の型 関数名(引数の型 変数名,…){
関数の中身...
(変数の宣言なども可能)
return
○; (←戻り値がvoidなら,省略可)
}
E-36
関数:戻り値を捨てる
double d_sq(double d){
double sq = d*d;
printf("%lf^2 = %lf\n", d, sq);
return sq;
実行結果
1.200000^2 = 1.440000
}
3.400000^2 = 11.560000
void main(){
double x;
戻り値を受け止めて,xに代入.
x = d_sq(1.2);
戻り値を受け止めずに,
d_sq(3.4);
捨てる.特に問題ない.
戻り値情報は失われるが,
}
関数は正しく実行される.
E-37
関数:複数のreturn
• 関数内に
return が
何個あってもよい.
実行結果
x=3 |x|=3
x=-4 |x|=4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
int zettaichi(int n){
if( n<0 ){
return (-n);
} else {
return n;
}
}
void main(){
int x, z;
x = 3;
z = zettaichi(x);
printf("x=%d |x|=%d\n", x, z);
x = -4;
z = zettaichi(x);
printf("x=%d |x|=%d\n", x, z);
}
E-38
関数:return
• return により,
関数は強制的に
終了する.
実行結果
AAAA
BBBB
戻り値が無いときは,
単に return; と記述
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
void funct(){
printf("AAAA\n");
printf("BBBB\n");
return;
printf("CCCC\n");
}
void main(){
funct();
}
E-39
関数:ローカル変数
1
2
3
4
5
6
7
8
9
10
void funct(){
int x;
x = 3;
abcd = 4;
}
void main(){
int abcd;
abcd = 5;
funct();
}
ブロックの外で
使おうとしている.
これは,NG.
コンパイルエラーとなる.
int abcd は,
このブロック内で
宣言されているため,
このブロックの中でしか
使用できない.
ブロック内の変数を
ローカル変数という.
ブロックの範囲
E-40
関数:仮引数と実引数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void func0(int x){
xが仮引数
x = 3;
}
void func1(int i){
i = 3;
}
void main(){
int i = 5;
printf("i=%d¥n", i);
func0(i);
printf("i=%d¥n", i);
func1(i); iが実引数
printf("i=%d¥n", i);
}
mainのiと,func0のxは
別の変数.
mainのiの値が,func0のxに
代入(コピー)される.
func0のxを変更しても,
mainのiには影響なし.
mainのiと,func1のiは
別の変数.
名前が同じ別の変数.
mainのiの値が,func1のiに
代入(コピー)される.
func1のiを変更しても,
mainのiには影響なし.
i=5
実行結果 i=5
i=5
E-41