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

, レポートに対するコメント , 第 3 章の補足 計算機言語 I 第 3 回前回の補足

N/A
N/A
Protected

Academic year: 2021

シェア ", レポートに対するコメント , 第 3 章の補足 計算機言語 I 第 3 回前回の補足"

Copied!
4
0
0

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

全文

(1)

計算機言語 I 3

前回の補足 , レポートに対するコメント , 3 章の補足

この資料: http://www.math.u-ryukyu.ac.jp/~suga/gengo/2019-1/03.pdf

1

変数の宣言と型

前回述べたように, Cのプログラムで変数を使うときには,予め型を指定して宣言する必要があります. れは,より高速に動作する実行ファイルを作りやすいようにするためです.

プログラムの実行中は,メモリの中にプログラムのコードや,変数の値が存在し,これらを処理することで結 果が得られます. 「実行中に必要となったメモリを順次確保する」という動作では,実行速度が遅くなりがち です. そこで,必要なメモリは,実効開始時に確保するという動作で,処理速度を上げるわけです.

C(Linuxのモデルとなった)Unix というOSを記述するために開発されました. OSの動作速度は,

ンピュータ全体の使用感に影響を与えますので,実行時にできる限り早く動作するプログラムを書けることが, Cの言語仕様に現れています.

規格と実装

上に述べたように, C, AT&T (American Telephone and Telegram)Bell研究所でUnixの記述用に 技術者が内輪で利用するために開発された言語処理系で,それが後に大学や企業を通じて一般に広まったもの です. Cが広く社会で利用されるようになった際に,「方言」,即ち, C の独自拡張が多く現れました. 高級言 語では, 一つのソースコードがあまり変更せずに色々な環境で使えるべきなのですが,「方言」のせいでそれが 成立しなくなりました. そこで, 1989ANSI (American National Standard for Industry,アメリカ工業規 )Cの言語仕様を定めました. この仕様は,その後何度か改定されています. 日本でもC 言語はJIS X 3010という形で日本工業規格(JIS)になっています.

現在利用してるC言語処理系は,これらの規格に沿う形で動作します(規格に準拠するという).

char

規格上, char型は,Cのプログラムを記述するのに必要な文字,記号全体の集合の1文字を保持できるデー

タ量」となっています. C を記述するのに必要な文字は, Ascii コードの文字集合に含まれるので, 規格上は char型は7bit以上の記憶域を持つ変数型となります(6bitだと64文字なので少し足りない).

Cchar型の規格をそのまま読むと,文字コードは, Asciiである必要はありません. 実際Main Frame( インフレーム)では,別の文字コードを利用したCの処理系があります.

この講義で使っている処理系では, char 型はAscii コードを利用しており, Asciiコードを含むことができ

1

(2)

8bit (1 Byte)の整数値を保持する形で実装されており,これは現時点で最も普及している形です.

現在では,この実装を逆利用して, char型を 8bit(1 Byte)の整数を保持するための変数として利用したり します. 例えば,画像ファイルでは,画素(ピクセル, pixel, picture elementの略)に対して,光の3原色RGB

(Red, Green, Blue)のそれぞれの値を1バイトの大きさでデータを持つ事が多くあります. 画像処理をする

ソフトでは,このRGBの値をchar型のデータとして処理するように記述する事もあります. 将来的に,この 実装が変わることは無いとは思いますが,本来的には, (処理系の実装に依存した)変なプログラムの記述です.

もうひとつのchar型の問題点として,次のような記述が可能である事があります. char moji=65;

これは, char型の変数moji Ascii値が65の文字(大文字のA)を代入して初期化するという, Cの仕様と しては正しい記述です. しかし, char型の変数に整数値を代入しているわけですから,意味的には変です.「文 法的には正しいが,冷静に考えると意味がおかしい.」というような仕様は,本来策定すべきではありませんが, (開発現場由来が理由で) Cでは,このような事がいくつかあります.

int, double型の範囲

これらも,有限桁数と有限精度をもつデータ型です. 理由は次です.

1. 上に述べたように,そもそもOS の開発用に作られたので, 開発の初期段階では極端に大きな整数の必 要性が無かった.

2. 現時点で,ほとんどの計算において,十分な範囲と精度があり,実用的である. 3. 桁数や精度の制限が無い処理系を開発するのは,大変である.

2

情報の欠落

Cの基本変数型では, 数値は範囲が有限の範囲に収まるものしか扱えません(その範囲を超えた数値を扱う には,特別なプログラムを書く必要がある). これが理由で,正しい計算ができない事があります. 前回の2 目のレポート問題は,その例です.

これ以外にもいくつかあるのですが, ここでは, 次を挙げておきます(残りは, レポートに対するツッコミ ).

異なる型の計算 教科書 p. 26にあるように, int 型とfloat 型の計算では, int 型がfloat型に変換されて計 算されます. 現時点での多くの処理系では, int, float型も32ビットのデータになります. ところで, float 型の仮数部は, 23bitしかありません. これは, 24bit 以上の整数型をfloat 型に変換するときに, 全ての情報をfloat型にできない事が起こる事を意味します. その際に情報の欠落がおきます.

前回のレポート問題の2. , この情報の欠落をIEEE-754 の規格に従って説明せよという意味ですので, 連休中にでも考えてみてください.

3

レポートへのツッコミ

レポートへのツッコミではありませんが, 2つ程注意を述べておきます.

2

(3)

1. 1年次の情報科学演習のMapleの回に紹介しましたが, e163πが整数値でないことを計算によって確 かめるには, 30桁程度の精度の計算が必要です(0<|e163π6403203744|<1/(640320)2). 素朴 Cの処理系のdouble , 16–17桁程度の精度しかありません. また, 情報の欠落により,e163π 精度はさらに落ちます.

2. レポート問題を次のようにプログラムすると警告文(warning)が出てきます. double a = 640320*640320*640320;

警告: 式内で整数がオーバーフローしました [-Woverflow]

これは,次の理由によります.

この講義のCの処理系では, 640320のような数字で始まり,小数点等が無い文字列は,整数値とし て扱われる.

処理速度向上のため,コンパイラが640320*640320*640320 を計算して,それが実行ファイルに書 き込まれるように処理する(実行時に上のかけ算をするのでは無い).

上の掛け算の結果は, int型の範囲をはみ出す

このような事を避けるには,次のようにコーディングします. double a = 640320.0*640320.0*640320.0;

レポートへのツッコミ

printfでの浮動小数点数の出力 printfで浮動小数点数を出力するには, 書式指定で%fを使います. %dと書 いた人が何名かいました.

#define PAI 3.14159265358979 この形で, πを定義すると, 情報の欠落が起きます. double型は, 最大17 桁程度の精度を持てるので,桁数が足りません.

#include<math.h> 前回述べましたが,これは,/usr/include/math.hの内容をプログラムソースに取り 込むという意味です. /usr/include/math.hには,M_PI が定義されていますから,このファイルを取 り込んだ時点で,πの値はM_PIで参照できます.

計算順序 (e163π6403203)744e163π(6403203+ 744) では,情報の欠落の起こり方が違うので, 答も異なります. 両方の計算結果を述べた素晴らしいレポートがありました.

4

教科書

3

章の補足

3章の内容はif文の話で,これは計算機概論で述べた Awkif文と全く同じです(AwkCの真似をし たのです). 教科書に真偽値をとる式の解説が詳しく書いてあるので,この辺は, 私からは多く解説しません. 注意して欲しい部分をいくつか述べておきます.

scanf

プログラムでキーボードからのデータを読み込む最も基本的な方法は, ライブラリ関数scanf()を利用す る事です. 面倒なところは, scanf()printf()の使い方が,完全に対称では無いところです. その辺の詳

3

(4)

しい話は,後の講義でも取り上げます. 詳しい事を知りたい方は,マニュアルコマンドを実行してください. man 3 scanf

真偽値 C(bool型を利用しない)プログラムでは,真偽値は整数値であり,偽が0,真は0以外となってい

ます. 教科書,プログラム3.3 では真値として1が出力されており,多くの実装はそうなっていると思 いますが, 1と確定しているわけではありません.

複文 C では, ブレイス{, } で囲んだ部分に複数の文(処理)を書いて, ひとまとまりの処理にします. if – elseでは,複文でなければ,そのあとの処理には,ブレイスは不要です. 教科書では,プログラム3.1, 3.2 でそのような例があります. しかし, p. 41の解説にあるように,後でプログラムを変更する可能性と人 間の可読性のために,ブレイスを利用したプログラムが,多くの場合推奨されます.

今回は,教科書 p. 46までのプログラムを実行してください.

レポート問題

次の2つをレポートしてください.

1. 次のように動作する入力した整数値をおうむ返しする動作をするプログラムを書け. 整数を入力してください >> -123

入力した値は -123 です.

2. 上のプログラムで, 3000000000(30)を入力したときの出力値を, プログラム内での動作を説明 することにより,説明せよ.

レポートする内容は, 1のプログラムソースおよび2の説明文. 件名: gengo2019-1 report 3-1,送り先: [email protected],締切56() 10:00(JST)

56()は授業日ですので注意してください.

4

参照

関連したドキュメント

教科書 p.93, 6.7 節 , 再帰 recursion の補足 再帰とは, 関数の処理の途中で自分自身を関数呼び出しすることです.. ただし, 教科書のHanoiの塔の様に再帰でしか書けないような処理もありますし, 繰り返し処理に変換する

置換マクロ プリプロセッサ の #defineは,見かけ上は関数の働きをする. この関数のような働きをするマクロを 引数付置換マクロ という.

また, char, short int, int, long int に対しては, unsigned を前につけると, それぞれ符号無しの型を 表し, signed をつけるとそれぞれ符号つきの型を表す..

time_t 型を人間が使いやすい時刻の構造体に変換するライブラリ関数がいくつかあり , List 13–3 では localtime という関数が利用されています.

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

上の search 関数の while 文を while(p-&gt;info !=x &amp;&amp; (p!=NULL)) に変えると , 見つからない値 を探すと実行時エラーになる. 上のプログラムで

exit() は引数値を shell 変数 status に返してプログラム を終了するライブラリ関数です .... /*

bash-4.4$ mkdir gengo bash-4.4$ cd gengo bash-4.4$ mkdir chap01 bash-4.4$ cd chap01 コマンドcdはchange directoryの略で, Gnome 端末のshellのワーキングディレクトリを変更するコ... この意味は, 計算機概論 I でやりましたので,