20130716

練習問題4


[next|prev|index]

1. 変数

計算を行うときにはデータを記憶しておく場所が必要です。例えば、プログラム自体の中にデータを書き込んでおくこともできます。次のプログラムは123*456を計算するプログラムです。

#include<stdio.h>
int main(void)
{
    printf("計算結果は%d",123*456);
    return 0;
}

123456のようにプログラムの中に直接データを書き込んだものをリテラルと呼びます。教科書では定数と呼んでいました。 しかし、途中の計算結果を記憶する必要がある場合もあります。こんな場合は値を書き換えるので定数は使えません。こんな時には変数を使います。

1/nのn=1から1000までの和を計算したいとき、

#include<stdio.h>
int main(void)
{
    int n;
    double total= 0;
    for(n = 1;n <= 1000; n++)
    {
        total+= 1.0/n;
    }
    printf("計算結果は%f", total);
    return 0;
}

のようなプログラムを書きます。ここでntotal変数です。nとtotalは計算の中で値が変わって行きます。

C言語では変数はデータ型を指定して作ります。繰り返しの回数を数えているnは整数型int、1/nの値を足しこんで合計を求める変数totalは倍精度の実数型doubleです。

変数のデータ型

C言語では変数に記憶できるのはデータ型が用意されたデータのみです。C言語の場合はchat、int、float、doubleの4つの基本データ型が定められています。

計算機はデータをメモリーにビットパターンとして記憶します。データとパターンの対応はこのデータ型で決まります。

データの標準入力からの読み取り

scanf関数を用いて1文字、整数、実数の3つのデータを読み取る。その後でprintf関数を用い、それぞれ文字コード(10進数表記)、16進数表記、逆数を標準出力へ書き出すプログラムを作りなさい。

次のような入力に対しての結果は出力のようになること。

入力:「a 123 3.14」

出力:「97 7b 0.318471」

ヒント:
3つのデータを読み取るには、3つの対応するデータ型の変数が必要です。
scanf関数を使うときは適切な書式指定子と変数のアドレスを渡すことに注意。
printf関数の16進数の文字列への変換を行う書式指定子は「%x」です

解答例

割り算に注意

7個の整数値「100 88 95 100 85 70 98」の平均値を実数で求めなさい。整数値7個はプログラム中にリテラルとして書き込んでくださ。

私の計算では平均値 90.857143でした。

解答例

floatとdouble

実数0.123456789をdouble型とfloat型の変数に代入し、printf関数で、それぞれ小数点以下10桁までを書きだすプログラムを書きなさい。

ヒント:

全部で12ケタかつ小数点以下10桁までの書式指定子は %12.10f です

C言語の実数は既定値でdouble型です。float型の変数にdouble型の値を格納する場合はキャストが必要です。例えば float f=(float)1.23456789;のようにキャストします。

解答例

※データのビットパターン表現が2進数であること、および書式指定子%fでの書き出しが四捨五入を行うため、小数点6桁程度の書き出しでは違いが見えません。

(番外編)int型の数値とビットパターン

int型は4バイトのメモリーを使い2の補数表示でデータを記録することが多い。ここでは0/1のパターンを表示するプログラムを作ってみよう。

メモリーのビットパターンを調べるにはビット演算子を使う。(教科書にも説明してあります)

  1. まず、int型の整数aを用意して標準入力からデータを変数aに読み込む。
  2. aのメモリーの一最下位の1ビットを調べるには、a&1の様なビットごとのand演算の結果を見ればいい。結果が0なら最下位ビットは0。そうでなければ1である。
    if( (a&1)==0) 最下位ビットは0の場合の処理;else 最下位ビットは1の場合の処理;
  3. aのメモリーのビットパターンを1ビット分下位にずらす。
    この処理はa=a>>1;のようなビット演算子で行う。
  4. 上の2つの処置を繰り返すとデータに対応するメモリーのビットパターンを下位の側から1つづつ調べることが可能だ。int型が4バイトなら32回繰り返せばいい。繰り返しの回数を数える変数が要りそうだ。int i;のように変数を用意しよう。
  5. 調べた結果を逆順で表示すれば0/1のビットパターンを解り易く表示できる。この為には32個の0/1を記憶する変数を用意すればいいのでchar bits[32];のように配列変数を用意しよう。

このように、色々と手順をかんがえたら、Cのプログラムを作成する。まずは全ての必要な変数を予め定義するとことから書き始めよう

解答例

変数の使い方

計数のための変数

0から1000までの数字をスペースで区切って順番に書き出すプログラムを作りなさい。

出力「0 1 2 3 4 5 6 7 8 9 10 11 12 13 14    ...」

for文を使って繰り返しの構文を利用するのが良いでしょう。for文を使うには、繰り返しの回数を数える変数が必要になります。

解答例

積算のための変数

n=1から10000までの合計「1+2+3+4+5+6+7+8+9+10+...」を計算しなさい。和は50005000になるはずです。

解答例

分岐のための変数

2次方程式ax2+bx+c=0の根を求めるプログラムを書きなさい。係数 a、b、cの値は標準入力からscanfで読み取ってください。

実行例

入力 「1  1  1」 <<x2+x+1=0 の 根は共役複素数 (-1±√3i )/2

出力「x1=-0.500000+0.866025i x2=-0.500000-0.866025i」

ヒント:

a,b,cは全て実数です。

判別式の値を格納する変数dが必要です。dの値によって処理が分岐するはずです。

ルートの計算は標準関数sqrt( )を絶対値の計算は同じくfabs( )を使います。これらの関数を使うにはmath.hのインクルードが必要です。

解答例 

まだ覚えているとは思いますが^^ 根の公式 

配列

沢山のデータを扱うとき、いちいち変数名を考えると面倒なことになります。C言語では沢山のデータを記憶するために配列を定義します。

配列は同じ型のデータを一列に並べて記憶する仕組みて、個々の値は添え字演算子を用いて参照します。

配列の利用

文字コード表

数字「0123456789」とアルファベット「ABCDEFGHIJKLMNOPQRSTUVWXYZ」の文字コード(正の10進数)を書き出すプログラムを書きなさい。

出力
0 48
1 49
2 50
. . .

文字を配列に入れておくと楽です。
chat numbers[ ]="0123456789"; のように初期化すると、文字列終端のコード0までを格納した配列が定義されます。

解答例

並べ替え

文字列”This is a pen. That is a book.”を文字コードの小さい順に並べ替えた文字列を書き出すプログラムを作りなさい。

実行結果は「       ..TTaaabehhiiiknoopssst」
前の方にあるのはスペースの文字です。

ヒント:

文字コード表の問題と同じで文字配列を使うのが良いでしょう。コード順に並べ替える方法は無数にあるので調べてください。

解答例

行列の積

3行3列の行列A,Bの積を計算するプログラムを作りなさい。

行列、A,Bはdouble型の2次元配列で表現すると良さそうです。他にも計算のための変数があるので作りながら考えてください。

 double A[3][3]={
   {1,0,0},
   {0,0,1},
   {0,1,0}
};
double B[3][3]={
   {1,2,3},
   {4,5,6},
   {7,8,9}
};
のような行列の積は
1.000000, 2.000000, 3.000000
7.000000, 8.000000, 9.000000
4.000000, 5.000000, 6.000000
となります

解答例