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

計算機言語 I 第 8 回関数 (その 2)

N/A
N/A
Protected

Academic year: 2025

シェア "計算機言語 I 第 8 回関数 (その 2)"

Copied!
6
0
0

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

全文

(1)

計算機言語 I 8 回 関数 ( その 2)

この資料: http://www.math.u-ryukyu.ac.jp/~suga/gengo/2021/08.pdf

Firefox の cache( キャッシュ ) のクリア

情報処理センターでは,各個人が作成できるファイルの総量を規制してます(Disk quotaあるいは Strage

quotaという). 情報処理センターが用意できる2次記憶装置の容量に限りがあるので,それを, 使用者全員で

分け合わなければならないからです.

ソフトウェアには,動作の途中でファイルを保存していくものがあります.Firefoxのようなウェブブラウ ザでは,アクセスした Webサイトのデータ(htmlファイルや画像ファイル)を cache(キャッシュ)という 形で保存しています.例えば,「戻る」というボタンがウェブブラウザにありますが,戻るボタンが押された際 には,ネットのデータにアクセスするより,キャッシュにあるデータにアクセスします. ネットからデータを読 むより,ディスクデータにアクセスする方が,遥かに速くデータが得られるからです

このウェブブラウザのキャッシュのせいで, 上で述べた個人の Disk quotaを越えるという現象が起きて いるようです.

次の手順で, Firefoxのキャッシュを消去して下さい. 1. Firefoxを起動する.

2. Firefoxの上部右側(URLを入力する欄があるところの右端)のメニューボタンをクリック

3. 現れるメニューから「設定」を選ぶ.

4. 左側の「プライバシーとセキュリティ」欄を選ぶ.

5. 中心となるウィンドウの中の「Cookieとサイトデータ」のところにある,「データを消去」ボタンを押 す.(これでキャッシュデータの消去ができます.)

6. 次の Firefoxを閉じたときに Cookieとサイトデータを消去するにチェックを入れておくと, Firefox

が原因で, Disk quotaが問題になることは無くなります.

レポートへのツッコミ

Cのプログラミングで関数を利用する理由は,次のふたつです.

(2)

レポート問題では, ヘロンの公式を利用した関数を書いていただきましたが,エラー処理は,「面積の値とし てはあり得ない, 0以下の数を返す」ということで実現する仕様にしたわけです. レポート問題は,「定められ た仕様通りのプログラムを書く」を問題にしています.

他にも関数設計の考え方はあり,例えばエラー処理を平方根を取る関数sqrtに任せるというのも,ひとつの 考え方です.

レポート問題に対する私が考えた模範解答は, 次です. 下のプログラムでは, Sは3角形を成さない正の 3 つの数を入力すると, 0以下になること(証明は各自考えること)を利用しています. これにより, 3角不等式を 用いたエラーチェックを簡易化しています.

「return文があると,そこで関数は値を返して処理を終了する」は覚えておいて下さい. double heron(double a, double b, double c)

{

double s, S;

if ( a<=0 || b<=0 || c<=0){/* 辺の長さは正 */

return 0.0;

}

s=(a+b+c)/2.0;

S=s*(s-a)*(s-b)*(s-c);

if (S <=0) { /* このとき 3角形にならない */

return S;

}

else { /* 面積は, S の平方根 */

return sqrt(S);

} }

レポートに対するツッコミですが,

• そもそも関数heronを作成していないものがありました.

• 3角不等式を間違えているものがありました.

• 3角不等式でエラーチェックするには, 3通りのチェックが必要です.

• sqrt に負の数を入力してしまうプログラムがありました.

• 辺の値が負の数になったことをチェックをした人は,少数でした.

(3)

教科書 6 章の補足 : 関数呼び出しに対する暗黙の型変換

上の関数heronがあったとして,次のようなプログラムを書いたとします. int a, b, c;

double area;

a=3; b=4; c=5;

area = heron(a,b,c);

...

つまり,double型の引数をとる関数heronに対して,int型の値を渡すとどうなるか? という問題です. この場合, a, b, c はdouble型に型変換されて, 関数に値が渡ります. 注意して欲しいのは, int→ doubleのような場合は, 変数の取り得る値の範囲が増えるので,問題は起きないのですが,double→intの ような場合は,変数の取り得る値の範囲が減るため「情報落ち」の現象が現れます. この辺も,関数の仕様策定 で難しくなる部分のひとつです.

教科書 6.4 節の補足

「Cの関数の引数は値渡し」は,いわゆる「構造化プログラミング」を実現するための言語仕様です. ただし, 値渡しだけでプログラムを書くのは,効率性を犠牲にすることもあるので, ポインタを利用した参照渡しも可 能にしてあるのです. このあたりの詳しい考え方は,次回のポインタの時に解説します.

教科書 p.92, 6.6 節の補足

ヘッダ(header)ファイルに対する解説がありますが,少し補足しておきます.

#includeは,cpp(Cプリプロセッサ)への指示で,そのあとに続くファイルの内容をプログラムソースに取 り込みます. ほとんどの場合,教科書にあるようにヘッダファイルと呼ばれるものを取り込みますが,それ以外 のファイルを取り込まないわけではありません. C のソースファイルを取り込んでも構わないし,プログラム で利用するデータを取り込んでも構わないのです.

この講義で利用しているstdio.h,math.hはヘッダファイルと呼ばれます. 多くの場合,ヘッダファイルに は,次の2つを記述します.

• cppのマクロ置換を利用した定数の定義

• プログラムソースに記述する関数のプロトタイプ宣言

(4)

教科書 p.93, 6.7 , 再帰 (recursion) の補足

再帰とは, 関数の処理の途中で自分自身を関数呼び出しすることです. 再び自分自身に帰ってくるので再帰 と呼ばれます.

計算機概論Iのmapleの講義の回で,再帰の話を1度しました. その際にも述べたことですが,再帰の利点, 欠点は次になります.

• プログラムの記述が簡潔で分かりやすく(読みやすく)なる.

• 関数呼び出しの度にスタック領域と呼ばれるメモリを消費するので,処理によってはメモリが足りなく なる.

• 関数呼び出しという動作が数多く起こるため,プログラムの動作が遅くなる(今回のレポート問題).

今回のレポート問題にある様に,再帰を繰り返し処理で書けるのであれば,実行時間を考えると,繰り返し処 理で記述方が望ましいのがほとんどです.

ただし, 教科書のHanoiの塔の様に再帰でしか書けないような処理もありますし, 繰り返し処理に変換する

のが大変な場合もあります. 後者の例としては,プログラム言語処理系の作成が良く取り上げられます. プログラム言語処理系では,次の動作をして実際にコンピュータで動作するプログラムを作り上げます. 字句解析 プログラムのソースコードを「単語(word)」に分解して,それがキーワードであるか, 数値である

か,識別子であるか,演算子であるかなどを調べる.

構文解析 上の単語の並びから,実際にコンピュータでしなければならない動作を確定させる.

例えば, Cを例にとると,「数から始まる文字列」があれば,それは数値に変換されますし,アルファベットか ら始まる文字列なら,それは,キーワードか識別子のどちらかをチェックします(字句解析). また,(x+y)*zの 様な式があれば,x+yを計算してその結果に zを掛けるという動作をさせるように機械語を生成します(構 文解析).

このような動作ができるようにプログラミング言語の文法が決まっているわけですが, それを記述するのに よく用いられるのが, 拡張バッカスナウア記法(Extended Backus–Naur form, EBNF)です. EBNFで記述 されたプログラム言語の処理系を作成しようとすると,次のような複数の関数にまたがる再帰処理を書くのが 最も自然です(書く方も書きやすいし,読む方も読みやすい). 実際, 言語処理系を作る際には,下のようなプロ グラムが描かれます.

(5)

func1() {

...

func2();

}

func2() {

...

func3();

}

...

funcN() {

...

func1();

}

(6)

レポート問題

締切: 6月14日(月) 10:00(JST)

a0=a1= 1,an+1=an+an1, (n≥1) で定義されるFibonacci(フィボナッチ)の数列について, 次の2 つのプログラムを書き,そのプログラムを提出するとともに, 3番目の結果をレポートせよ. ただし,どちらの 関数も,unsigned long long型(符号無し64bit整数)の変数を利用して,a50の正しい値が表示できるよう にすること. printfでのunsigned long longの出力の指定方法は,%llu. (man 3 printf を参照).

1. 繰り返し (for でも while でも良い) を用いて, 自然数 nの入力に対して, an を出力する関数 fibonacci(int n)を書き,main()では,a50を出力するプログラム.

件名: gengo2021 report 8-1.

2. 再帰を利用して, 自然数nの入力に対して,anを出力する関数fibonacci(int n)を書き,main()で は,a50を出力するプログラム.

件名: gengo2021 report 8-2

3. 上の2のプログラムの実行は終了するか? 2のプログラムが終了するなら,上の1, 2のプログラムにつ いてtimeコマンドでレポートされる内容を提出せよ.

件名: gengo2021 report 8-3.

timeコマンドは,time ./a.outで,a.outの実行に対して要したCPUの使用時間をレポートします.

参照

関連したドキュメント

その内容は, 必ずしも quicksort の実装ではなく処理系依存ですが, 多くの場合, quicksortの最後の欠点を少し改善したプログラム が実装されているようです.. Bash4-4$ man 3 qsort 次のプログラムは, qsortを用いて,seiseki_t data[41];をscore

これらの特別な意味を持つ語をキーワードと言ったり予約語 ( 言語によってあらかじめ 意味が予約されている語 ) と言ったりします.. 例えば

[r]

このことを利用して list 8–9 と同じ動作をするプログラムを書くと , list

fread() では , 読み込んだ値を第一引数のポインタ値が指すメモリに順に格納 ( コピー )

[r]

次のよ うな内容になります .https://github.com/okumuralab/algo-c/blob/master/src/matutil.c をダウン ロードするかコピペして適当に編集するのが早道です

教科書で用いている gcc とは GCC(GNU Compiler Collection) の中の C コンパイラで , 多くの OS に移 植されている無料のコンパイラ処理系です... ld