情報処理1 解説サイト

データ型

今回はデータ型のおさらいと課題の解法について解説したいと思います.

前回の授業”関数”では関数に渡す値のデータ型と関数の引数のデータ型,関数のデータ型とその戻り値のデータ型とその代入先の変数のデータ型を一致しなければコンパイルエラーとなっていたと思います.このコンパイルエラーはそのデータ型それぞれのbitサイズを合わせてほしいためです.今回の授業でそれが納得してくれれば幸いです.
あとは基本的には授業ページを参照してもらい,「こんなデータ型があるんだな」,「変数の宣言にはスコープを考慮しなくては」と各自復習してください.また,将来大規模なプログラムを書くときには今回の授業で習った構造体を用いることでコードの煩雑さが緩和され,可読性が上がるのでデバッグもしやすくなるので,構造体は是非マスターしてほしいですね.
では,問題の解説をしたいと思います.

  • 5組

1. 摂氏温度を華氏温度に変換する関数c2fをつくりなさい. 引数として実数1個,戻り値も実数とする.
main関数を作成し,関数を呼び出して正しく動作するかチェックすること.
(摂氏=Celsius度,華氏=Fahrenheit度の意味や変換方法は,各自で調べること.)

#include...

??? c2f(...)
{
    ....
    return ???;
}

int main(void)
{
    float T;  /* 温度を格納 */
    printf(...);
    scanf(...);
    
    printf("摂氏 %f 度は,華氏 %f 度です.\n", T, c2f(T) );
    return 0;
}

この問題のポイントとなるのは関数自体のデータ型および引数のデータ型の定義です.このポイントさえ押さえられれば簡単な問題です.


2. 1 から n までの整数の和 ∑n を計算する関数 Sum を作成しなさい.
(この関数の引数は整数 n ,戻り値として計算した和を返す関数とすること.)

#include...
	
??? Sum(...)
{
    ....
    return ???;
}
	
int main(void)
{
    int n;
    printf(...);
    scanf(...);
	
    printf("1から %d までの和は %d です.\n", n, Sum(n) );
    return 0;
}

この問題のポイントとなるのはSum()内でおそらくfor()文等で計算した値をreturnできるかどうかにあります.おそらく上記の問題が解けたならば,この問題も楽勝でしょう.


3. キーボードから3次元の空間座標を入力すると,原点からの距離を返す関数pytagを作成せよ. キーボードからの入力および結果の画面への表示は全て main 関数内で行うこと.
ヒント:平方根の計算は,sqrt関数を使う.要#include

#include<math.h>

???? pytag????
{
    ....

	float root_two = sqrt(2.0);  /* sqrt関数で,平方根の計算ができる */
}

int main(...)
{
    ...
    return 0;
}

/*
実行例:
x座標を入力してください:3
y座標を入力してください:4
z座標を入力してください:5
距離:7.071068

x座標を入力してください:-5
y座標を入力してください:2
z座標を入力してください:-8
距離:9.643651
*/

この問題のポイントとなるのはmath.hを利用することにあります.たとえば,距離を求めるためにデカルト座標系でいうところのx, y, z成分それぞれの2乗和が必要になりますが,単純に x*x + y*y + z*zで求めるのではなく,以下のように求めることも可能です.

float x = ...;
float y = ...;
float z = ...;
int a = 2;

x_jijou = pow(x, a);
y_jijou = pow(y, a);
z_jijou = pow(z, a);

このpow()関数はmath.hからincludeしています.


4. 整数を引数として,引数が素数かどうかを判定する関数 IsPrime() 関数を作成しなさい.
関数 IsPrime 内では素数の判定のみ行い,画面表示などは全て main 関数内で行うこと.
戻り値の意味などは各自で設定して良いが,コメントとしてソースコード中に記述しておくこと.
(例えば,素数の場合の関数の戻り値は1,それ以外は0とする,など.)

#include...
	
??? IsPrime(...)
{
    ....
    return ???;
}
	
int main()
{
    int n;       /* 整数を格納 */
    printf(...);
    scanf(...);

    ....
}

この問題のポイントは関数内で判定した処理をどのように戻り値を与え,その戻り値をmain関数内でどのように処理をするかです.
多くの場合,c言語では二値判定の場合はbool型というものを使用します.今回の課題では例として以下のように使用します.

#include <stdio.h>

bool Judgment(int n){
        
        ........
        
        if(nが素数){
              return true;
        }else{
              return false;
}

int main()
{
     int num = ...;
     bool judge = Judgment(num);
     
     if(judge){
         printf("numは素数\n");
     }else{
         printf("numは素数でない\n");
     }
     return 0;
}

このboolはtrueという文字列をソースコード中では1として扱い,falseは0として扱います.詳しいことは各自でぜひ調べてみて下さい.


5. 三つの実数を引数に取り,それらの中央値(メディアンという)を返す関数 median を作成せよ.
main 関数を用いて確認すること.

#include...
	
??? median(...)
{
	....
	return ???;
}
	
int main()
{
    printf(...); scanf(...);	
    ....
}

/*
実行例:
a= 10.5
b= -3.9
c= 0.3
中央値は 0.3 です.
*/

この問題の攻略はメディアンというものを各自で調べ,その数学の定義をコードとして書き起こせるかにかかっています.それさえ出来ればあとはメディアンを戻り値として返すだけです.

  • 6組

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

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

アスキーコード表とquiz1,2,3を理解していれば難しくないと思います.一度の実行で一度入力、変換、表示したら終了して構いません。

.... += 'A' - 'a'

のようにするとアスキーコード表を覚えていなくても大文字小文字変換することができます.




2.QUIZ4を参考にして,一桁の自然数(数値)を引数にとり,文字(数字)を返す関数 toascii() を作れ. 但し変換にprintfなどを用いてはならない.
10進数を16進数に変換するときは10進数を16で割って余りを計算します.

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");
}

char型の’0'にnumberを足していきましょう、そのままだとおそらくコンパイルで怒られるのでキャストしてから足しましょう。


3.unsigned short int型(16bit整数)の変数を引数として受け取り, 2進数を印字する関数
void print_short2binary(unsigned short);
を作成せよ.様々な値をテストするテスト用main()も作れ. テスト用を行うときの文字定義(コンパイルスイッチ)は"TEST"とせよ.

【ヒント:以下のプログラムの足らない部分を埋めなさい】
//  年組番号 氏名
//  print_short2binary.cpp
#include <stdio.h>

void print_short2binary(unsigned short si)
{
    for(int i=....
        printf("%d", ....);

        if(!(i%4))  // 見やすくするために4桁毎にスペースを入れる  
            printf(" ");
    }
    printf("\n");
}

#if defined(TEST)
int main(void)
{
    print_short2binary(0x1234);
    print_short2binary(0x1248);
    print_short2binary(0x8421);
    print_short2binary(0xAAAA);
    print_short2binary(0x5555);
}
#endif


4.unsigned short int型の変数に256以上の値を入力したとき,下位8ビットはどんな数値になるかを 調べるため,次のようなプログラムを作りたい. 下位8ビットの部分を返す関数 unsigned char LSB8(unsigned short) をつくり, 2進数のビットパターン,16進,10進の3通りで表わす. この関数をチェックするテスト用main関数も同時に作れ.

【ヒント:以下のコードの穴埋めをせよ】
// 年組番号 氏名
// lsb8.cpp
#include "print_short2binary.h"
unsigned char lsb8(unsigned short us) 
{
    ....
    return uc; 
}

#if defined(TEST)
#include <stdio.h>
int main(void)
{
    for(int i=0; i<8; i++){
        unsigned short x = 252 + i;
        printf("%d : %04X : ", x, x); 
        print_char2binary( lsb8(x) );
    }   
}
#endif

5.上記のunsigned short型の変数のうち,上位8ビットはどんな数値になるかを調べたい. 上位8ビットの部分を返す関数 unsigned char MSB8(unsigned short) をつくり, 2進数のビットパターン,16進,10進の3通りで表わせ. テスト用main関数は上記と同様で良いが,関数のテストが正しく行える必要はある.

【ヒント:以下のコードの穴埋めをして正しいプログラムとせよ】
// 年組番号 氏名
// msb8.cpp
#include "print_short2binary.h"

unsigned char msb8(unsigned short us) 
{
    ....
    return uc; 
}

#if defined(TEST)
#include <stdio.h>
int main(void)
{
    for(int i=0; i<8; i++){
        unsigned short x = 0x4321 + i*0x1111;
        printf("%5d : %04X : ", x, x); 
        print_char2binary( msb8(x) );
    }   
}
#endif