第6章 関数,引数,変数,記憶クラス Cの関数の種類

第6章 関数,引数,変数,記憶クラス
Cの関数の種類
テーマ
z 関数の種類
z 関数の標準形
z 引き数と戻り値
z 関数の戻り値と宣言
z 4つの記憶クラス
z 再帰
z 標準数学関数
① ch = getchar();
→ 関数の値を返す
(戻り値,返り値)
② printf("¥n");
→ 関数の値はない
関数の標準形
関数の宣言
• プロトタイプともいう
関数の宣言
関数の宣言
関数の型 関数名(引き数の宣言)
関数の型 関数名(引き数の宣言)
{{
自動変数の宣言;
自動変数の宣言;
• <例>
int max(int, int);
float length(int, float);
void idle(void);
関数の内容;
関数の内容;
}}
• 関数の戻り値がintのときは戻り値のint を省
略できる.(デフォルト)
<例> max(int, int);
処理の流れ
引き数と戻り値
型を合わせる
引き数
戻り値
func
値が
コピーされる
呼び出し側
w = func(t, u);
2つの方法
• 関数の値
• 引き数の値
C言語,東京工業大学,鈴木 博
func(x, y)
int i, j, p;
⋯
return (p)
型を合わせる
1
#include <stdio.h>
#define min(a, b) (a < b) ? a: b /* Macro */
int max(int, int); /* "max(int, int);" is available */
max
max == 22
int main()
max
{
int j;
max == 22
float x=1.0, y=2.0;
min
min == 11
j= max(1, 2);
min
min == 1.000000
1.000000
printf("max = %d¥n", j);
printf("max = %d¥n", max(1, 2));
printf("min = %d¥n", min(1, 2));
printf("min = %f¥n", min(x, y));
}
int max(int i, int j) /* "max( i, j);" is available */
{
return ((i>j) ? i: j);
}
マクロを使うときの注意
#define min(x,y) ((x < y) ? x: y)
main()
{
int i, j;
i = 7; j = 10;
printf(“%d”, min(i++, j++));
}
printf(“%d”, ((i++ < j++) ? i++ : j++));
#include <stdio.h>
#include <stdio.h>
int getint();
int spc(int);
int main()
{
int s =0 , d;
while ((d = getint()) != -9999) { s += d;}
printf("sum = %d", s);
11
}
22
33
int getint()
44
{
int n;
55
scanf("%d", &n);
-9999
return(n);
-9999
sum
}
sum == 15
15
int main()
{
int j;
for (j = 1; j <= 10; j++)
{
spc(j);
printf("hello c!¥n");
}
}
4つの記憶クラス
変数には4つの記憶クラス(class
of storage)がある
••
••
••
••
自動変数(automatic
自動変数(automatic variable)
variable)
外部変数(external
外部変数(external variable)
variable)
スタティック変数(static
スタティック変数(static variable)
variable)
レジスタ変数(register
variable)
レジスタ変数(register variable)
C言語,東京工業大学,鈴木 博
hello
helloc!
c!
hello
helloc!
c!
hello
helloc!
c!
hello
helloc!
c!
hello
helloc!
c!
hello
helloc!
c!
hello
helloc!
c!
hello
helloc!
c!
hello
helloc!
c!
hello
helloc!
c!
int spc(int j)
{
int i;
for ( i= 0; i<j; i++) printf(" ");
}
自動変数
• ある関数の中だけで使用される
• 関数の{ }の中で宣言される
• ローカル変数といわれることもある
• プログラムが関数の中に入るときに設定さ
れる
• 初期化は自動的にされない
• 関数を抜け出すときに消滅する
2
外部変数
自動変数
• すべての関数からみて外側で定義されている
func()
• どの関数からでも読み出し書き換えできる
• プログラムの開始時に初期化される
(特別な指定がなければ変数の内容はゼロが
設定される)
int i, j;
i, jは消失する
jは消失する
func()
• グローバル変数,大域変数ともよばれる
int i, j;
前のi,
前のi, jとは
jとは
異なる
#include <stdio.h>
void incr(void);
int flag; /* global variable */
int main()
{
int i=0;
while (i < 5)
{
incr();
printf("%d %d¥n",++i, flag++);
}
}
11
22
33
44
55
void collatz(void);
void input(void);
long n;
11
33
55
77
99
int main()
{
int iteration=1;
input();
while (n>1)
{
collatz();
printf("%6ld", n); iteration++;
if ((iteration % 10) == 0) printf("¥n");
}
printf("¥n Iteration = %d¥n", iteration);
}
void collatz(void){ if (n %2 == 0) n /= 2; else n = 3*n + 1;}
void incr(void)
{
flag++;
}
void input(void)
{
printf("input an arbitrary integer¥n");
scanf("%ld", &n);
printf("%6ld", n);
}
スタティク変数
input an arbitrary integer
1025
1025 3076 1538 769 2308 1154 577 1732 866 433
1300 650 325 976 488 244 122
61 184 92
46
23
70 35 106
53 160
80 40 20
10
5
16
8
4
2
1
Iteration = 37
C言語,東京工業大学,鈴木 博
•
•
•
•
修飾語:static
<例> static int n;
関数から一度抜け出ても値が消えない
初期化される
3
void count(int);
void dummy(int);
int main()
{
int p=0;
printf(" p¥t i¥t n¥t j¥n¥n");
for (p = 1; p < 4; p++) count(p);
/*for (p = 1; p < 4; p++) {count(p); dummy(p);}*/
}
void count(int s)
{
int i, j;
static int n;
for (i=1; i<=3; i++, n++, j++)
printf(" %d¥t %d¥t %d¥t %d¥n", s, i, n, j);
}
void dummy(int s) { int i, j=s;}
レジスタ変数
long int P(long int);
int main()
{
int i, max_i;
for (i=1; i<= MAX; i++)
printf("%12ld¥n", P((long)i));
}
long int P(long int n)
{
return ((n==0) ? 1: n*P(n-1));
}
C言語,東京工業大学,鈴木 博
pp
ii
11
11
11
22
22
22
33
33
33
11
22
33
11
22
33
11
22
33
nn
00
11
22
33
44
55
66
77
88
jj
00
11
22
33
44
55
66
77
88
for
for (p
(p == 1;
1; pp << 4;
4; p++)
p++)
{count(p);
{count(p); dummy(p);}
dummy(p);}
pp
ii
11
11
11
22
22
22
33
33
33
11
22
33
11
22
33
11
22
33
nn
jj
00
11
22
33
44
55
66
77
88
139992
139992
139993
139993
139994
139994
11
22
33
22
33
44
再帰関数(recursive)
• 修飾語:register
• <例> register int i, j;
• メモリ上ではなくCPUのレジスタ上に置かれる
変数
• <例> 8086 ax, bx等のレジスタ
• 本来,計算速度が速くなるはずであるが,あま
り効果がない
#include <stdio.h>
#define MAX 12
for
for (p
(p == 1;
1; pp << 4;
4; p++)
p++)
count(p);
count(p);
11
22
66
24
24
120
120
720
720
5040
5040
40320
40320
362880
362880
3628800
3628800
39916800
39916800
479001600
479001600
• ある関数から,同じ関数を呼び出す
• 同じ結果を,非再帰的なアルゴリズムで実現
可能な場合がある
• 終結処理が関数内に明記されている
終結条件 → そのときの戻り値
標準数学関数
① 三角・逆三角 (trigonometric):角度 x の単位はラジアン(radians)
double sin(double x)
x に対する sin(x)を与える.
double cos(double x)
x に対する cos(x)を与える.
couble tan(double x)
x に対する tan(x)を与える.
double asin(double x)
- 1 < x < +1 に対して arc sin(x)ラジアンを与える.
double acos(double x)
- 1 < x < +1 に対して arc cos(x)ラジアンを与える.
double atan(double x)
x に対して arc tan(x)ラジアンを与える.
double atan2(double y, double x)
x, y に対して atan(y/x)ラジアンを与える.
4
④ 近い値の整数:
double ceil(double x)
② 双曲線(hyperbolic) :角度 x の単位はラジアン(radians)
double sinh(double x)
x に対する sinh (x)を与える.
double cosh(double x)
double tanh(double x)
x に対する cosh (x)を与える.
x に対する tanh (x)を与える.
double floor (double x)
x より大きいか等しい,最小の整数値を返す.
(天井 ce iling と見なせる整数値 ce il(1.6)→2,
ce il(−1.6)→−1)
x より小さいか等しい,最大の整数値を返す.
(床 floor と見なせる整数値 floor(1.6)→1,
floor(−1.6)→−2)
⑤ 絶対値,その他:
③ 指数・対数 (exponential and logarithmic) :
double exp(double x)
double log(double x)
double log10(do uble x)
double pow(double x, double y)
double sqrt(double x)
x
指数関数 e
自然対数 ln (x),範囲は x > 0
常用対数 log10 (x),範囲は x > 0
x の y 乗 xy
平方根 x ,範囲は x > = 0
double fabs(double x)
double ldexp(double x, int n)
x の絶対値 | x | を返す.
x * 2n を返す.
double frexp(double x, int * m)
x = y * 2m の y を返し,m を*m に入れ
double modf(double x, double * ip)
る.x = 0 では y, m とも 0 とする.
浮動小数点数 x を同じ符号の整数部 ip
double fmod(double x, double y)
x/y の余りを浮動小数点表示で返す.符
と小数部に分け,小数部を返す.
号は x と同符号で表す.
C言語,東京工業大学,鈴木 博
5