Transcript int n

オブジェクト指向言語
オブジェクト指向言語演習
第05回 C言語の基礎
関数
スケジュール(C言語)
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
受講ガイダンスとプログラム開発基礎
Linuxの使い方と簡単なC言語プログラムの作成,実行
C言語 変数と式
(2004/10/4)
C言語 制御と流れ
(2004/10/4)
C言語 変数と式(復習)
(2004/10/18)
C言語 制御と流れ(復習)
(2004/10/18)
C言語 関数
(2004/10/25)
C言語 配列
(2004/10/25)
C言語 文字列の表現
(2004/11/1)
C言語 ポインタ
(2004/11/1)
C言語 構造体とユーザ定義型
(2004/11/8)
C言語 ファイル
(2004/11/8)
中間試験
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
2
出席確認
 出席確認WebPage
 http://www.iis.it-hiroshima.ac.jp/att/
 講義用WebPage
 http://www.iis.it-hiroshima.ac.jp/~nagasaka/
lect/oo/2004/
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
3
プログラミング言語 C
関数
( Function )
カプセル化構造-関数
 関数とは
 ある処理(仕事)をするブロック(かたまり)
 入力(複数)
 処理
 出力(1つ)
値
値
処理
出力
値
入力
 関数の使用
 関数の宣言
 関数の呼び出し
 関数の定義
関数
たとえば、与えられた数の2乗を計算す
る簡単な関数f(x)の例
5
入力
27.Sep.2004
25
f(x)
Object Oriented Language - Y.Nagasaka: [email protected]
出力
5
関数の定義方法
 一般的な関数の定義は以下の通りである。
入力1
関数の型名
関数名( 引数名1の型名 引数1, .... ,
引数名nの型名 引数n) {
入力n
内部変数定義;
文1;
文2;
・・・
}
27.Sep.2004
return 関数値;
関数名
引数1
関数
関数値
引数n
引数とは関数に与えるパラメータ
のこと
関数の出力値
return値とも呼ぶ
Object Oriented Language - Y.Nagasaka: [email protected]
6
整数の正のべき乗を計算する関数の例(1)
 関数名をpowint、y=xpを計算するとする。関数の
入力はx,p(整数型)であり、関数からの出力値はy(整
数型)となる。
int powint (int x, int p) {
yは関数powint内
だけで有効
int y = 1;
while (p-- > 0) {
y *= x;
}
pの値を次々に減らしていき、
0になるまで繰り返す。すな
わち、このループはp回繰り
返される。
return y;
}
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
7
整数の正のべき乗を計算する関数の例(2)
 作成されたpowintを使う。
#include <stdio.h>
int powint(int x, int p);
int main(void){
int i, j;
for (i=0; i <= 10; i++) {
j=powint(2, i);
printf(“%d\t%d\n”, i, j);
}
return 0;
}
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
プロトタイプ宣言
プログラム内で使用
される関数の名前や
引数の順序、型など
を記述する。
関数呼び出し
powint関数を呼び出
す。ここでは、xとし
て2が使用されている
ので2のi乗が計算さ
れ、それがjに代入す
る。
8
関数を含むプログラムの構造
 プログラムの一般形式
#include <stdio.h>
#include <ヘッダファイル名>
プロトタイプ宣言
int main(void){
変数宣言;
メインプログラム
return 0;
}
関数型
}
27.Sep.2004
関数名(仮引数) {
関数内で有効な変数の宣言;
関数のプログラム;
return 結果の値;
ヘッダファイルを読み込む。
このヘッダファイルにはプ
ロトタイプ宣言や定数定義
が書かれている。
stdio.hはシステムの標準関
数のプロトタイプ宣言など
が記述されており、
/usr/include/stdio.hに
入っている。
#include “ファイル名”
任意のディレクトリにある
ファイルを読み込むことが
できる。
Object Oriented Language - Y.Nagasaka: [email protected]
9
関数の呼出し手順(1)
 組み合わせを求める関数combiを作成する。
組み合わせは、nCr=n!/(r! * (n-r)!)で定義される。
int combi ( int n, int r) {
int i, nk=1, rk=1, nr=1;
for (i = 1; i <= n; i++) {
nk *= i;
}
局所変数(local variable)
i, nk, rk, nrは関数
combi内のみで利用可能
1.n!を求める。
for (i = 1; i <= r; i++) {
rk *= i;
}
2.r!を求める。
for (i = 1; i <= (n-r); i++) {
nr *= i;
}
3.(n-r)!を求め
る。
return nk / (rk * nr );
}
27.Sep.2004
4.nCrを計算す
Object Oriented Language - Y.Nagasaka: [email protected]
10
関数の呼出し手順(2)
 関数を呼び出す側のプログラム
#include <stdio.h>
int combi(int , int); /*プロトタイプ宣言では引数名を省略可能*/
int main(void){
int t, m;
for (t=0; t <= 5; t++) {
for (m=0; m <= t; m++){
printf(“%dC%d=%d\t”, t, m, combi(t,m));
}
}
printf(“\n”);
return 0;
}
combi(m, t)
m, tの値を
呼び出し
n, rに受け渡す
int combi(int n, int r)
27.Sep.2004
呼び出し側の引数(m,t)を実
引数と呼び、
関数側の引数(n,r)を仮引数
と呼ぶ。
Object Oriented Language - Y.Nagasaka: [email protected]
11
関数の呼出し手順(3)

関数呼び出しの手順
1.
2.
3.
4.
5.

値渡し(called by value)



関数呼び出しが行われる
実引数の値を仮引数にコピー
その関数の定義部分を実行する
計算結果をその関数の値として返す
関数を呼び出したプログラムへ制御を戻す
関数の呼び出しのときに、実引数の値を仮引数にコピーして渡
す方法
C言語の場合、通常の呼び出し方法が値渡しである。
参照渡し(called by reference)


27.Sep.2004
関数の呼び出しのときに、実変数のメモリアドレスを仮引数に
コピーして渡す方法
scanfの時の変数の前の「&」、ポインタ(次週以降に説明)
Object Oriented Language - Y.Nagasaka: [email protected]
12
関数の中から別の関数を呼び出す(1)
 combi関数の中で同じような処理が3回あった。
int combi ( int n, int r) {
int i, nk=1, rk=1, nr=1;
for (i = 1; i <= n; i++) {
nk *= i;
}
for (i = 1; i <= r; i++) {
rk *= i;
}
for (i = 1; i <= (n-r); i++) {
nr *= i;
}
return nk / (rk * nr );
}
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
13
関数の中から別の関数を呼び出す(2)
 階乗を計算する関数factを定義して利用する。
#include <stdio.h>
int fact(int);
int combi(int, int);
int main(void){
メインプログラム;
}
/*プロトタイプ宣言*/
/*プロトタイプ宣言*/
int fact (int n){
int i, fact=1;
for (i = 1; i <= n; i++) {
fact *= i;
}
return fact;
}
int combi ( int n, int r) {
return fact(n) / (fact(r) * fact(n-r) );
}
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
14
外部変数と局所変数
 外部変数(global variable)
 関数の外部(外側)で宣言された変数
 すべての関数から参照可能
 どの関数から参照しても、その変数の中身は同一
 局所変数(local variable)
 関数の内部(内側)で宣言された変数
 それぞれの関数の内部でしか有効ではない
 関数の外側からは参照できない
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
15
外部変数と局所変数の例
#include <stdio.h>
void vartest(int a);
int g = 100;
int main(void) {
外部変数
int a, b, c;
g ← 100
a = 1;
b = 2;
c = 3;
局所変数(main関数)
printf("main
: (g,a,b,c) = (%4d,%4d,%4d,%4d)\n",
a ← 1
g, a, b, c);
b ← 2
vartest(a);
c ← 3
printf("main
: (g,a,b,c) = (%4d,%4d,%4d,%4d)\n",
g, a, b, c);
}
局所変数(vartest関数)
void vartest(int a) {
a ← 関数の引数 a
int b, c;
b ← 20
b = 20;
c ← ?(宣言のみ)
printf("vartest: (g,a,b,c) = (%4d,%4d,%4d,%4d)\n",
g, a, b, c);
return;
外部変数gは関数内からも
}
参照できる
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
16
自動変数とstatic変数
 自動変数
 関数の仮引数や局所変数のように、関数が呼ばれる毎にそ
の変数に対するメモリ領域を確保する。
 autoという記憶クラス指定子があるが、関数内で何も指定
しなければ、auto付であると認識される。
 static変数
 プログラム起動時に1度だけ、その変数に対するメモリ領
域が確保される。
 関数が何度も呼ばれる場合、その変数は同じ領域(同じ
値)を使用することになる。すなわち、他の関数から参照
できない外部変数のようなものである。
 書き方:
 static 変数型名 変数名;
 static int time;
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
17
変数の通用範囲(スコープ) (1)
 自動的な変数の通用範囲
 自動的な変数には、関数の仮引数、auto変数がある
 関数の仮引数の通用範囲は、その関数のブロック内だけで
ある。
 <<プログラムの形式5.8>> (p.200)
 auto変数の通用範囲は、その変数が定義されたブロック内
だけである。
 <<プログラムの形式5.10>> (p.200)
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
18
戻り値の無い関数、引数の無い関数
 戻り値の無い関数(void型関数)
 関数の結果から戻り値を必要としない場合
void 関数名(引数型 引数,...){
return;
}
 p.168参照
 引数の無い関数
 引数の無い関数の場合
関数型 関数名(void){
...............
}
 p.180参照
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
19
変数の通用範囲(スコープ) (2)
 静的な変数の通用範囲
 静的な変数には、 static変数、外部変数がある。
 static変数の通用範囲はその変数が定義されたブロック内
だけである。
 <<プログラムの形式5.11>> (p.201)
 外部変数の通用範囲は、その定義の直後からそのコンパイ
ル単位(通常はファイル)である。ただし、extern宣言す
れば、他のコンパイル単位からも参照可能。
 <<プログラムの形式5.12>> (p.202)
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
20
課題1
 二つの整数変数の引数の和を計算して結果を戻す関
数plusを作成し、それを利用して以下の実行結果に
なるようにしなさい(ファイルoo07-1.c)。
int plus( int a, int b);
% ./oo07-1
Input two integer numbers
4 5
4+5=9
%
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
21
課題2(1)
 階乗を求める関数factとべき乗を求める関数powint
を利用して、n!/xnを求める関数pow_fact関数を作
成しなさい(ファイルoo07-2.c)。
 ただし、pow_fact関数は引数に整数値をとるが、戻
り値は実数となることに注意しなさい。
float pow_fact(int x, int n);
/*プロトタイプ宣言*/
 factとpowintはそれぞれ教科書のリスト5.16
(p.185)とリスト5.2 (p.164)を参照しなさい。
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
22
課題2(2)
実行例
関数pow_factを作成しな
さい。
mainプログラムの例
% ./oo07-2
Input number
5
1
2
3
4
5
%
1.000000000
0.500000000
0.222222224
0.093750000
0.038400002
#include <stdio.h>
int powint(int, int);
int fact(int);
float pow_fact(int, int);
int main(void) {
int i, n;
printf("Input number\n");
scanf("%d",&n);
for (i=1; i <= n; i++) {
printf("%10d
%20.9f\n",i, pow_fact(i, i));
}
}
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
23
コンパイルと実行
 まずはじめに
 作業ディレクトリの作成
一度実行すればよい
% mkdir ~/wrk/
% mkdir ~/wrk/oo/
 次に




作業ディレクトリへの移動
プログラミング
コンパイル・リンク
実行
% cd ~/wrk/oo
% vi lect01-1.c
% gcc -o lect01-1 lect01-1.c
% ./lect01-1
* C言語プログラムのファイル名は、.c でなければならない
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
24