joho1-2016の日記

情報処理実習1の解説ブログです.皆さんが課題を解く時の助けになれば幸いです.

第6回 データ型

更新が遅くなり申し訳ありませんm(_ _)m

第6回の授業では,データ型について勉強しました.

我々人間と,コンピュータでは扱えるデータには違いがあり,これを理解せずプログラムすると,意図しないエラーが起こることもあります.
そして,これは経験上ですが,この手のエラーはコンパイルは通ってしまい,実行時に生じることが多々あり,デバッグが非常に厄介だったりします.今回の授業の内容は全て覚えるのはなかなか難しいですが,今後PCを使おうと思ってる人には是非知っていて欲しい内容です.

ビット(bit)とバイト(Byte)
コンピュータの記憶容量を数える際に使う単位で,ビット(bit)はその最小単位になります.そしてコンピュータは0と1の2値しか記憶しないので,1bitで表現できる数は,0か1になります.また,このbitを8つ集めたものをバイト(Byte)になります.

8bit = 1Byte

進数
我々が主に扱う0~9までの数字で数を表現するものを,「10進数」と呼びます.これに対し,コンピュータは0と1のみの「2進数」で記憶を行います.そして,あまり馴染みがないかもしれませんが,0~Fまでの「16進数」というものもあります.コンピュータの2進数を表記すると人間にはとても理解しにくいので,わかりやすい表現として16進数が扱われます.

変数
これまでの講義で扱ってきた変数も,割り当てられた要領だけメモリが確保されています.表は講義ページを参照してください.この事から,割り当てられた変数で表現できる以上の数を代入しても,正しい数は得られないため,エラーが起こります.しばしばエラーという形ではなく,正しくない数を返してくる事もあります.この場合は非常に厄介ですね...こんな事が起こらないようにするためにも,各変数に割り当てられたメモリのサイズ表は定期的に確認しておきましょう!

変数のスコープ,auto変数とstatic変数,グローバル変数は講義ページの通りです.長くプログラムを書く先輩としてアドバイスするならば,同一プログラム内に同名の変数があるのは,一部の例外(for文のカウンタ変数iなど)を除いて避けるべきです.例えそれがauto変数であっても,作った直後でない限り混乱しやすくなり,無駄にプログラムを読み返す時間を増やすことになるでしょう.

定数
変数と違って,値が変化しないものとして,定数がある.これらは講義ページにあるように,数値定数文字定数文字列定数と言うものがあります.ところで,この記事の最初の方で述べていますが,コンピュータは0か1しか記憶しません.なのに,文字を扱えるのはなぜでしょうか?
答えは,「文字を数で表現し,その数を記憶している」からです.そして,数と文字の対応を表にしているものがアスキーコード表なのです.この表は16進数で表現されていますが,これは1桁が4bit={2^4}=16で表現されるため,16進数表記なのです.

型変換
(1)代入時の型変換
左辺と右辺の型が異なる場合,左辺の型に変換される.

int a;
double b = 3.14159265358;
a = b;         //これはint型に変換
実行結果:
3

(2)式中の変換
式中の型が異なる場合,制度の高い型に統一される.

精度高 double > float > long > int > char 精度低

(3)キャスト
型を一時的に強制変換できる方法もあります.

float x = 3.14159265358;
int y = (int)x;       //float型のxは一時的にint型に変換された!

独自の型作成
C言語では,ユーザ自身が独自に変数型を作成できる.これは後々プログラミングをとても楽かつ見やすくしてくれるものなので,是非覚えておいてもらいたい.書き方は講義ページを参照してください.

以上で今回の講義のおさらいは終わりです.以下,各クラスの課題の考え方です.

5組
1.キーボードから実数 r を入力すると,小数点以下を切り捨て,切り上げ,四捨五入した値をそれぞれ表示せよ.
ヒント:四捨五入はどのようにしたらよいでしょう...0.5を加えて切り捨てればOK.

実行例(1):

r = 2.5
切り捨て = 2
切り上げ = 3
四捨五入 = 3

実行例(2):

r = 7.3
切り捨て = 7
切り上げ = 8
四捨五入 = 7

この課題のポイントは,
 ①明示的型変換
です.これまでに習った型として,intやfloatがありました.実はこれらは,宣言時とは別の型に強制的に変換することができます.これを「キャスト」といいます.そしてその特徴の1つとして,実数型(float)から整数型(int)への変換時には,小数点以下は切り捨てられるというものがあります.例えば,f=2.5という実数型の変数を整数型に変換(キャスト)すると,f=2となります.これを用いれば,切り捨て,四捨五入はできますね.切り上げについてですが,一番手っ取り早いのは,小数点を切り上げる関数(プログラミングにおける関数とは,目的の処理を行うために呼び出すものを指す)を使うことです.ただ,これはまだ習っていないことを使用するため,使いたくないと言う人がいるかもしれません.そんな人は,問題文のヒントを参考にすると,例外は多少生じますが,ほとんどの場合に目的の結果を得ることができるはずです.キャストの方法や小数点切り上げの関数のプログラム方法は,自分で検索してみましょう!

2.キーボードから線分の長さとして三つの整数 l, m, n を順次入力し,この線分にて三角形が作成可能かどうか画面に表示せよ.

実行例(1);
l = 3
m = 4
n = 5
三角形です.
		
実行例(2)
l = 10
m = 2
n = 3
三角形はできません!

この課題のポイントは,
 ①三角形の成立条件
です.これさえ知っていれば,条件文で簡単にプログラミングできますね.三角形の成立条件は高校数学で習うはずなので,ここでは説明しません.忘れてしまった人は,検索しましょう!

3.1 + 1/2 + 1/4 + 1/8 + ... + 1/2n + ... を計算せよ. 値が収束(項を追加しても,変化しなくなること)するまで計算せよ.
(もちろん,答えは2である.)

実行例:
	
1.000000000
1.500000000
1.750000000
1.875000000
.
.
.
.

この課題のポイントは,
 ①値の収束判定
です.今回は答えが教えられているので,和が2を超えた時にループを終了でも問題はないと思います.別な方法としては,あらかじめ収束判定値というものを用意しておき,現在の項{a_n}と一つ前の項{a_{n-1}}の差が収束判定値以下になった時にループを終了するものがあります.この収束判定問題というのは,プログラミングにおいてしばしば出てくる問題で,収束値の分からない場合などには,後者の方法を使って収束判定が行われます.

4.直角三角形の直角を挟む二辺の長さを実数 a, b として入力し,斜辺の長さを計算して画面に表示せよ.
平方根の計算には,下記のように sqrt関数を利用すると良い.

実行例(1)
a= 1.0
b= 1.0
斜辺の長さ = 1.4141356

実行例(2)
a= 3.0
b= 4.0
斜辺の長さ = 5.0000

この課題のポイントは,
 ①平方根の計算
です.問題文の通り,sqrt関数というものを使うと計算できるのでやってみてください.

5.関数 y = f(x) = x2 - x,(0 < x < 1) について,関数の最小値を数値的に求めよ.(解は x = 0.5 のとき y = -0.25 である.)
x=0から始めて刻み幅を dx = 0.0001 等としてxを徐々に増加させ,f(x-dx) >= f(x) <= f(x+dx) となる x を探す.
for や while文などの繰り返しと,break を使用せよ.

この課題のポイントは,
 ①繰り返し計算の刻み幅
です.みなさんはこれまで繰り返し計算の際のループ処理(forやwhile)を行う際,カウンタ変数iを整数として扱い,その刻み幅は1(i++又はi=i+1と書いていたと思います)だったと思います.しかし,その刻み幅は1である必要はなく,そして整数である必要もありません.今回の問題でいうと,0.0001刻みで繰り返し計算を行い,問題文に書かれている条件を満たした時にbreakでループを抜け出すプログラムを書くと,この課題は終了です!

6組
1.QUIZ1,2,3 を参考にして,入力した文字が大文字であれば小文字に変換し, 小文字であれば大文字に変換するプログラム作成しなさい. また入力は半角文字のみとする. キー入力と表示以外は組み込み型の関数は使わずに実現して下さい.

実行例:
文字を入力して下さい: M
m
文字を入力して下さい: e
E
文字を入力して下さい: i
I
文字を入力して下さい: j
J
文字を入力して下さい: I
i

この課題のポイントは,
 ①大文字と小文字の認識
です.QUIZ1~3を参考にすればいいので,アスキーコード表を使うことは自明ですね.そしてアスキーコード表を見ると,同じアルファベットの大文字と小文字は下位4bitは同じですね.つまり,上位4bitに対して何かしらの条件処理をすれば,小文字->大文字,大文字->小文字の変換はできますね.

2.QUIZ4を参考にして,一桁の自然数(数値)を引数にとり,文字(数字)を返す関数 toascii() を作れ. 但し変換にprintfなどを用いてはならない.

char toascii(int number)
{
    // write your code down here.
}

int main(void)
{
    for(int i=0; i<10; i++){
        char c = toascii(i);
        printf("%c",c);
    }
    printf("¥n");
}

この課題のポイントは,
 ①数字から文字への変換
です.QUIZ4において,文字としての数字(0x30~0x39)を数値(0~9)に変換はできましたね.そして,その時に,関数atoi( )では,引数に対してどんな処理がされていますか?今回の問題はその逆をやればいいだけですね.

3.QUIZ5 を参考にして,2点の三次元座標A(x,y,z),B(p,q,r)を入力すると 外積を計算する関数 cross_product() を作成せよ.

この課題のポイントは,
 ①独自の変数型作成
 ②外積計算
です.①はQUIZ5と全く同じで大丈夫なので,省略します.②は,QUIZ5の関数add( )の中身を外積の式に則って計算するよう書き換えれば解けますね.

以上で課題の考え方について終わりです.
もう授業では何も言いませんが,命名規則守ってください!
また,授業もだいぶ進んでプログラミングに慣れてきた人も多いと思いますが,インデントを意識して書いている人はまだまだ少ないように感じます.授業中の先生の書き方や,講義ページの解答例をよく見て,インデントを意識しましょう.C言語はあまり影響ありませんが,プログラミング言語の中にはインデントがおかしいだけでコンパイルエラーが生じる言語というのもあります.まだ習い始めで変な癖がない内から,綺麗なコーディングを身につけましょう!