プログラミング実習II 期末試験・想定問題 [S1] 変数と式

プログラミング実習II 期末試験・想定問題 [S1] 変数と式


(S1_1) 下記のプログラムは,1 + 1/2 + 1/3 + … + 1/nを求めるために実装したものである. しかしながら,2点バグが潜んでおり結果が正しく出力されない.

  1. プログラム中に2つ潜んでいるバグを修正しなさい. ただし,書き換えてよい範囲はプログラム中に示されている.
  2. なお,数百行規模のプログラムになると目視だけでバグが潜んでいる個所を見つけることは困難である. そのため,print文を用いたデバッグが必要不可欠となる. 仮に本問題のバグを目視で発見できなかったとして, どのようなprint文をどの場所に挟めばバグを発見できるか考えてみよ.
  3. (**)がコメントに入っている行について,変数 result を1つだけ 用いて同じ計算が行われるように書き換えよ. (ヒント:複合代入演算子を用いるとよい)

#include <stdio.h>

int main(void)
{

    int i,n;
    double result=0;

    //ここから
    printf("Input n>>");
    scanf("%lf",&n);

    for( i = 1; i <= n; i++ ){
        result = result + ( 1 / i );      // (**)
    }
    //ここまで

    printf("result=%f\n",result);

    return 0;
}

(S1_2) 下記のプログラムを実行したところ出力結果が以下のようになった.

  1. i=31のときの出力結果が明らかに異常であるが何故か?
  2. ★ 変数を unsigned int 型とし,printf出力時に書式を %u とすると,i=31の結果を正常に出力できる. unsigned int 型について説明するとともに,扱える値の最小値と最大値はどのように変化するか答えよ.

#include <stdio.h>
int main(void)
{
    int i;
    int sum=1;

    for(i=1;i<=31;i++){
        sum=2*sum;	//
        printf("i=%d → sum=%d\n",i,sum);
    }
}

(S1_3) 以下を満たすようにプログラムを書き換えよ。

#include <stdio.h>

int main(void)
{
    int pay, eatout, rest;

    printf("1ヶ月の給料を入力してください>>>");
    scanf("%d", &pay);
    printf("外食した回数を入力してください>>>");
    scanf("%d", &eatout);

    printf("自由に使えるお金は%d円です。\n", rest);

    return 0;
}

(S1_4)★ インクリメント演算子は, 前置演算子として使うか後置演算子として使うかによって挙動が変化する. 下記のプログラムを実行した場合の出力結果はどのようになるだろうか?

#include <stdio.h>
int main(void)
{
    int result;
    int x1, x2, y1, y2;

    result = 10;
    x1 = result++;
    printf("line1-> x1=%d result=%d\n",x1,result);

    result = 10;
    x2 = ++result;
    printf("line2-> x2=%d result=%d\n\n",x2,result);

    result = 10;
    y1 = --result;
    printf("line3-> y1=%d result=%d\n",y1,result);

    result = 10;
    y2 = result--;
    printf("line4-> y2=%d result=%d\n",y2,result);
}

(S1_5)★★ 任意の入力された2進数を10進数に変換するプログラムを作成しなさい.

  1. 手計算でできないことをコンピュータにさせることは不可能.
  2. 例えば,int binary[32]のような配列を用意して,入力例の各桁の値をbinary配列に格納できれば,変換は容易である(変換方法を知っていれば).
  3. 上で述べた格納処理はループ処理内で,入力例に対して除算や剰余算を用いれば可能である.

(S1_6)★★ 任意の10進数を2進数に変換するプログラムを作成しなさい.

(S1_7)★★

  1. 現在のコンピュータは32bitが主流であるため,扱える整数の範囲は-2^31 〜 2^31-1 である. つまり解が2^31-1 = 2147483647 を超える計算は単純にはできない(オーバーフローを起こす) もし現在のコンピュータが3桁の整数範囲(0〜999)の値しか扱えないとして, 500+700=1200のような扱える整数範囲を超える加算結果を出力するにはどうすれば良いか?

  2. 加減乗除の計算を多倍長演算を用いて行いなさい.