青山学院大学

前期試験 ・ 2017 年 7 月 27 日 4 時限実施 ・ ページ

授業
科目
計算機実習 I 学生番号 学科 学年 フリ
ガナ
  評点
                   氏名    
担当者 DÜRST, Martin J.、松原、
豊田、長谷川、盛川

英語の用語 / English Terms (20 点)

プログラミング一般やプログラミング言語 C/C++ において使われる次の英語の用語の日本語訳と説明を書きなさい。日本語訳ではできるだけ片仮名を使わないようにしてください。
Provide Japanese translations (avoiding Katakana where possible) and explanations of the following English terms used with programming in general or the programming languages C/C++.

indirection operator
間接演算子 (*); ポインタが指す値を返す演算子

heap
ヒープ; 動的メモリの確保に使わらるメインメモリの領域

compound statement
複文; {} 内で囲まれる複数の文が一つの文とみなされるもの

actual parameter
実引数; 関数に実際に渡される値のこと

warning
警告; 問題の可能性の私的; コンパイル可能だが、残さないで修正した方がよい

element
要素; 配列で格納されるものの一つ; 配列の長さは要素の数

orthogonality
直行性; 複数の概念が独立して、全ての組み合わせが可能な現象

logical operator
論理演算子; 複数の条件を論理的に結び付き、真偽を割り出す演算子 (例: &&, ||)

identifier
識別子; プログラムの中のもの (変数、関数、型) を識別する名前

type cast
型変換演算子; 型の変換 (例: 整数⇒小数点数) を行う演算子

式の評価 / Evaluation of Expressions (16 点)

次のテーブルの式の値を計算しなさい。なお、変数 iint i; と定義されている。
Evaluate the expressions in the table below. i is defined as int i;.

番号 式 / Expression 値 / Value 番号 式 / Expression 値 / Value
例/Example 2+3 5 例/Example 3*5 15
25 / 10 2 700 - 50+70 720
512 >> 3 64 13 & 21 5
17 ^ 29 12 19 << 5 608
(int)0.0259E8 2590000 35 % 9 8
i=7, 0[&i] 7 400 << 17>>21 25
i=15, ++i, i-- 16 2 > 3 && 4 ? 7 : 9 9
'Z' - 'A' 25 077 63
0x23 35 (double)(45/10) 4.0

前期試験 ・ 2017 年 7 月 27 日 4 時限実施 ・ ページ

プログラムの問題の指摘 (21 点)

下記のプログラムは繰り返し二つの文字から構成される面白い模様を出力する。入力 (一回に付き一行) は前景文字、背景文字、模様の幅、模様の高さ、前景文字を置く場所を決めるための除数である。 このプログラムには様々なレベルや種類の間違いや不備がある。授業で習った点や指摘されそうな点も含め、コメントの形で問題と修正方法を簡単に記述しなさい。 問題の数は合計で 21個。できるだけ沢山の問題を見つけなさい。同じ問題が二回以上ある場合、最初の一回しか指摘しないこと。 / The program below repeatedly creates an interesting pattern from two letters. The input (one line for one repetition) contains the foreground and background characters, the width and height of the pattern, and the divisor used to decide on the intervals between forground characters. In this program, there are some errors and defects of various kinds and levels. Indicate the problems and how to solve them, taking into account what you learned in the lecture. The overall number of problems is 21. Find as many problems as you can. If a problem appears more than once, only indicate the first appearance.

入出力の例 (一回の繰返しのみ) / Example input and output (one repetition only)

-@ 30 3 4
-@@@-@@@-@@@-@@@-@@@-@@@-@@@-@
@@-@@@-@@@-@@@-@@@-@@@-@@@-@@@
-@@@-@@@-@@@-@@@-@@@-@@@-@@@-@
#include<stdio.h>  // 例: include 後、スペースを追加 / space missing after include

int main (void) {  // { の前に改行
    char foreground, background;// EOF の区別のため、foreground は int で定義すべき
    int height, haba; // 変数名の言語を統一: haba ⇒ width
    int d; // 短すぎる変数名、改善例: divisor
           // != が = より優先度が高いので、(foreground=getchar())
    while (foreground=getchar() != -1) { // EOF が -1 という保証がない: -1 ⇒ EOF
        int i, j, k; // k を 0 に初期化する必要がある

        backround = getchar(); // backround ⇒ background
        scanf("%d", &haba)  // セミコロンが足りない
        scanf("%d", height);  // height ⇒ &height
        scanf("%f", &d); // d が整数なので、%f ⇒ %d
        // getchar(); などで改行を読み飛ばす必要がある
        i = 0;
        while (i<haba) { // 回数が決定なので、while の代わりに for を使用すべき
            for (j=0; j<=height; j++) { // <= ⇒ <
                if (k%d = 0) // 代入ではなく、等しいかどうか比較: ==
                        putchar(foreground); // インデントが多すぎ
                else
                        putchar(background);
                k = k + 1; // インクリメントなので、k++; (またはせめて k += 1;)
            // { が一個足りない
            putchar("\n"); // putchar は一文字出力なので、"\n" ⇒ '\n'
            +++i; // + が一個多すぎ
        }
    } // return 0; が足りない
}

授業へのコメント (合計 6 点)

この授業で一番分かりにくかったことを書きなさい。(具体的に書いてあれば内容にかかわらず 3 点)

@@@@

この授業で一番勉強になったことを簡単に説明しなさい。(具体的に書いてあれば内容にかかわらず 3 点)

@@@@

青山学院大学

前期試験 ・ 2017 年 7 月 27 日 4 時限実施 ・ ページ

授業
科目
計算機実習 I 学生番号 学科 学年 フリ
ガナ
  評点
                   氏名    
担当者 DÜRST, Martin J.、松原、
豊田、長谷川、盛川

構造体を使うプログラム (25 点)

ある製品の評価のデータを処理するプログラムを作りなさい。合計ちょうど100人の利用者から年齢 (満何歳)、性別、製品の評価 (0 から 100 の間の整数) を入力し、利用者の最大年齢、女性の数、製品評価の平均を出力する。プログラムの作成条件は、 利用者ごとのデータに構造体を使用すること、入力・計算・出力をしっかり分けることである。入力の範囲のチェックは必要ない。プログラムは二段組みで書いてよい。 / Create a program to process the data from a product evaluation. For exactly 100 users, read in their age (at their last birthday), their gender, and their product evaluation (an integer between 0 and 100). Use a structure to store the data for each user. Clearly separate input, calculations, and output. There is no need to check the input ranges. You can write the program in two columns.

入出力例 (利用者2人の場合)
Example Input and Output (for 2 users)

User #1
Age? 20
Gender (m=1, f=2)? 2
Evaluation? 50

User #2
Age? 30
Gender (m=1, f=2)? 1
Evaluation? 45

Max age: 30
Female users: 1
Average evaluation: 47.50
  
#include <stdio.h>

#define N_USERS 100

typedef struct {
    int age;
    int gender;
    int eval;
} User;

int main(void)
{
    User users[N_USERS];
    int max_age = 0;
    int female_count = 0;
    double eval_total = 0;
    int i;
    
    for (i=0; i<N_USERS; i++) {
        printf("User #%d\n", i+1);
        printf("Age? ");
        scanf("%d", &users[i].age);
        printf("Gender (m=1, f=2)? ");
        scanf("%d", &users[i].gender);
        printf("Evaluation? ");
        scanf("%d", &users[i].eval);
        printf("\n");
    }

    for (i=0; i<N_USERS; i++) {
        if (users[i].age > max_age)
            max_age = users[i].age;
        if (users[i].gender == 2)
            female_count++;
        eval_total += users[i].eval;
    }

    printf("Max age: %d\n", max_age);
    printf("Female users: %d\n",
               female_count);
    printf("Average evaluation: %.2f\n",
               eval_total/N_USERS);

    return 0;
}

  

前期試験 ・ 2017 年 7 月 27 日 4 時限実施 ・ ページ

関数 / Functions (合計 18 点)

プログラムの穴埋め (12 点)

次のプログラムは整数を素因数分解 (prime factorization) した結果を次のように表示するものである。 このプログラムが正しく動作するように空欄を埋めなさい。ただし,入力のチェックは省略する。
The program below outputs the prime factorization of an integer in the way shown below. Fill in the blanks to make the program work correctly. Input checks are omitted.

実行結果 / Execution Result

Input a number: 180
2 * 2 * 3 * 3 * 5

プログラム / Program

#include <stdio.h>
#include <math.h>

 int  isPrime (int pri)
{
    int i, isq = (int)sqrt( pri );
    for (i=2; i<= isq ; i++)
        if ( pri % i ==0)
            return 0;
    return 1;
}

void primeFactorization (int *list, int num, int div)
{
    int i;

    for (i =  div ; i <= num; i++)
        if ( isPrime( i )  && num%i==0) {
            num /= i;
             *list  = i;
             primeFactorization (++list, num, i);
            break;
        }
}
void printFactors (int *list)
{
    int i;
    for (i=0; list[i] != 0; i++) {
        if (i != 0)  printf(" * ");
        printf("%d",  list[i] );
    }
    printf("\n");
}

int main(void)
{
    int num;
    int primes[100] = { 0 }; // 配列のすべての要素を 0 に初期化
                             // initializes all elements of the array to 0
    printf("Input a number: ");
    scanf("%d", &num);
    primeFactorization( primes , num, 2);
    printFactors(primes);

    return 0;
}

次ページに続く / continued on next page

青山学院大学

前期試験 ・ 2017 年 7 月 27 日 4 時限実施 ・ ページ

授業
科目
計算機実習 I 学生番号 学科 学年 フリ
ガナ
  評点
                   氏名    
担当者 DÜRST, Martin J.、松原、
豊田、長谷川、盛川

表示形式の変更 / Changing the Output Format (6 点)

前ページのプログラムの printFactors 関数を修正して、次のような表示にしたい。次の空欄を埋めなさい。他の関数には変更を加えないものとする。空欄を埋めなさい。/ We want to fix the printFactors function in the above program so that the result appears as below, without changing the other functions. Fill in the blanks.

実行結果 / Execution Result

input num: 180
2^2 * 3^2 * 5

プログラム / Program

void printFactors (int *list)
{
    int i, exp = 1;
    for(i=0;  list[i] != 0; i++){
        if (list[i] ==  list[i+1] )
            exp++;
        else {
            printf("%d", list[i]);
            if (exp >  1 )  printf("^%d", exp);
             exp  = 1;
            if (list[i+1] != 0)  printf( " * " );
        }
    }
    printf("\n");
}

printf の書式 (11 点)

下記の変数の定義後、表の printf 文を実行する。各出力を 1文字ずつ表に記入しなさい。スペースは SP、小数点は DOT と書く。 'a' の文字コードの番号は十進数で 97。 / After the variable declarations below, the printf statements in the table are executed. Write each output character-by-character in the table. For space, write SP, for the decimal dot, write DOT. The number of the character 'a' in decimal is 97.

char c = 'h'; double d = 222.22; float f = 44.4; int i = 14, k = 5; char *s = "Aoyama";
番号 printf 文字 1 文字 2 文字 3 文字 4 文字 5 文字 6 文字 7 文字 8 文字 9 文字 10
printf("%d", i); 1 4
printf("%8s", s); SP SP A o y a m a
printf("%-8s", s); A o y a m a SP SP
printf("0x%x", i); 0 x e
printf("%-5d", i); 1 4 SP SP SP
printf("%05X", i); 0 0 0 0 E
printf("*%3c*", c); * SP SP h *
printf("%%d%%", i); % d %
printf("%.4f", f); 4 4 DOT 4 0 0 0
printf("%.3E", d); 2 DOT 2 2 2 E + 0 2
printf("%*d", k, i); SP SP SP 1 4
printf("%+d", i); + 1 4

前期試験 ・ 2017 年 7 月 27 日 4 時限実施 ・ ページ

C++ (合計 22 点)

下記のプログラム断片は大学の学部の定員 (capacity) と実際に在籍する学生の数 (enrollment) を管理するクラスを定義している。/ The program fragment below defines a class for managin the capacity and the actual number of enrolled students (enrollment) for departments at an university.

class Department {
  public:
    Department(int cap);
    Department(int cap, int enr); // [1]
    int getCapacity(void);
    int getEnrollment(void);
    int overCap(void);       // [2] 在籍数が定員数を超える場合、その差 (超えない場合、0) を返す
  private:                   //     if enrollment>capacity, returns difference, otherwise 0
    int capacity;
    int enrollment;
};

Department::Department(int cap) { // 新設学部用 (在籍する学生が 0)
    capacity   = cap;             // for new departments (no enrolled students)
    enrollment = 0;
}

int Department::getCapacity(void)    { return capacity;   }
int Department::getEnrollment(void)  { return enrollment; }

定義の完成 / Completion of Definitions (10 点)

上記のクラスで、宣言されているが定義されてない部分 ([1], [2]) が存在する。その部分の定義および正式名称を書きなさい。 / The above class contains two parts ([1], [2]) that are declared but not defined. Give the definitions for these parts and their technical terms.

[1] 定義 (実装) / definition (implementation):  正式名称 / technical term: コンストラクタ

Department::Department(int cap, int enr) {
    capacity   = cap;
    enrollment = enr;
}

[2] 定義 (実装) / definition (implementation):  正式名称 / technical term: メンバ関数

int Department::overCapacity(void) {
    if (enrollment > capacity)
        return enrollment - capacity;
    else
        return 0;
}

クラスの使用 / Class Use (6 点)

下記の main 関数の出力文に合うように、空欄を埋め、出力を完成しなさい。 / In the main function below, fill in the blanks to complete the output so that it matches the output text.

int main(void) {
    Department engineering(200, 240);
    Department science(150);
    Department literature;  // [3]
    Department literature.capacity = 200, literature.enrollment = 120;  // [4]

    printf("Department of Literature overcapacity is %d\n",  literature.overCap()    );
    printf("Department of Science enrollment is %d\n",     science.getEnrollment()   );
    printf("Department of Engineering capacity is %d\n",  engineering.getCapacity()  );
}                                       // 次ページに続く / continued on next page

青山学院大学

前期試験 ・ 2017 年 7 月 27 日 4 時限実施 ・ ページ

授業
科目
計算機実習 I 学生番号 学科 学年 フリ
ガナ
  評点
                   氏名    
担当者 DÜRST, Martin J.、松原、
豊田、長谷川、盛川

プログラムの修正 / Correcting the Program (6 点)

前ページの main 関数の [3], [4] の行に問題がある。それぞれの問題とその解決策を説明しなさい。 / The main function on the previous page contains problems in lines [3] and [4]. Explain the problems and their solutions.

[3] の問題 / Problem [3]: デフォルトコンストラクタがありません。デフォルトコンストラクタを追加するか、または Department literature(200); などに定義を変更しないといけません。
 
[4] の問題 / Problem [4]: メンバ変数 capacity と enrollment が private: のため、メンバ変数に直接代入できません。 カプセル化のための private: をやめるか、setCapacity などのセッタのメンバ関数を追加しないといけません。

ポインタ / Pointers (合計 18 点)

定義と代入 / Definitions and Assignments (6 点)

対応する C 言語のコードを書きなさい。/ Write the C code corresponding to each explanation.

  1. char 型のポインタ pt の宣言 / Declaration of pt, a pointer to char: char *pt;
  2. サイズ 100short 型のポインタの配列 ss の宣言
    Declaration of ss, an array of size 100 of pointers to short: short *ss[100];
  3. 最大 200 バイトの入力用バッファの変数 b の宣言
    Declaration of an input buffer b of up to 200 bytes: char b[200];
  4. double 型のポインタ xp への double 型の変数 x のアドレスの代入
    Assignment of the address of a double variable x to xp, a pointer to double: xp = &x;
  5. int型のポインタ ip への int 型の配列 is の先頭アドレスの代入
    Assignment of the address of the first element of is, an array of int, to ip, a pointer to int: ip = is;

演算子 (6 点)

int 型の変数 iと、 float 型のポインタ pq が定義されたとき、 ippq の間に可能な四則演算を一つずつ選択し、 表を埋めなさい。/ For variables i (of type int), p, and q (both of type float), select a basic arithmetic operation (+-*/) between both i and p, and p and q, and complete the table.

可能な演算の C 言語のコード
C code with operators
演算結果の説明 / Explanation of operation result
i / p p+ip-i など p から float i個分先のアドレス
p / q p-qq-p など pq のアドレスの差 (float 何個分なのか)

配列と動的メモリ / Arrays and Dynamic Memory (6 点)

C 言語における配列の定義とライブラリ関数 malloc の呼び出しの共通点と相違点を,可能な限り専門用語を用いて簡潔に説明しなさい。 / Explain the commonalities and differences between definition of an array and use of the library function malloc in C.