基本情報技術者試験の過去問と解説
[TOP] [午前分野別] [午後分野別] [キーワード索引] [令和元年秋午前] [令和元年秋午後]

平成17年 秋期 基本情報技術者 午後 問10
問10   C言語

次の C プログラムの説明及びプログラムを読んで,設問1〜3に答えよ。

〔プログラムの説明〕

ある大学における成績出力用プログラムである。

(1) この大学では,学期終了時に学生の履修科目成績一覧を図1に示すレコード様式

でファイルに出力する。学生数は 15,000,科目数は 2,000 であり, 得点は 0 〜 100 の整数値である。

  学生キー 学生氏名 科目名 得点 科目名 得点  科目名 得点
(例) 02498 基本五郎 情報処理 2 25 化学実験 50 英会話基礎 1 67

    図1 履修科目成績一覧のレコード様式

(2) 出力に必要なデータは,図2に示す3種類のファイルに記述されている。

 科目キー 科目名

0000   情報処理1
0001   情報処理 2
0002   数値解析
       …
0752   化学実験
       …
1997   英会話基礎 3
1998   英会話基礎 4
1999   英語応用
 科目ファイル
 course.txt
     学生キー 学生氏名

00000   設計花子
00001   情報太郎
00002   開発次郎
       …
02498   基本五郎
       …
14997   試験守
14998   単元三郎
14999   言語大輔
 学生ファイル
 student.txt
     科目キー 学生キー 得点

1932    00472    34
1932    09755    79
0357    10253    41
      …
0752    02498    50
      …
0173    13712    13
0173    00638    78
0173    03581    61
 成績情報ファイル
 record.txt

    図2 読込みファイル群の例

(3) プログラムは,はじめに関数 init を呼ぶことで,図2に示した3種類のファイルから 図3に示すようなリスト構造をメモリ上に構成する。 科目キー courseKey の科目名は,char 型の配列 courseName[courseKey] に格納される。 また,学生キー studentKey の学生情報は STUDENT 型の構造体 student[studentKey] で表現され,メンバ studentName には学生氏名が,メンバ rFirstCourse にはその学生 成績情報を表すリストの先頭へのポインタが格納される。 学生の各履修科目についての成績情報は RECORD 型の構造体で表現し,メンバ score には得点, メンバ courseName には科目名へのポインタ,メンバ rNextCourse には他の履修科目の 成績情報へのポインタが格納される。

    図3 データ構造例

(4) プログラム中で定義されているその他の関数の説明は次のとおりである。

void regist(int courseKey, int studentKey, short s);
機能:新たに RECORD 型の構造体を生成し,メンバ score に得点 s を代入する。 また,この得点が学生キー studentKey の科目キー courseKey についてのものであると いう情報を設定する。
void writeCourses();
機能:全学生分の履修科目成績一覧をファイルに出力する。

(5) このプログラムでは,次のライブラリ関数を用いる。

void *malloc(size_t size)
機能:size バイトの領域をメモリ上に割り付け,割り付けられた領域へのポインタを返す。 メモリ割付けに失敗した場合は NULL を返す。

〔プログラム〕

#include <stdio.h>
#include <stdlib.h>
#define NUM_STUDENT 15000 /* 学生数 */
#define NUM_COURSE 2000   /* 科目数 */
#define MAX_WORD_LENGTH 21
 
struct RECORD {           /* 成績情報 */
    char *courseName;     /* 科目名へのポインタ */
    short score;          /* 得点 */
    struct RECORD *rNextCourse;  
                          /* 次の履修科目の成績情報へのポインタ */
};
struct STUDENT {          /* 学生情報 */
    char studentName[MAX_WORD_LENGTH]; 
                          /* 学生氏名 */
    struct RECORD *rFirstCourse;       
                          /* 一つ目の履修科目の成績情報へのポインタ */
} student[NUM_STUDENT]; 
char courseName[NUM_COURSE][MAX_WORD_LENGTH]; 
                          /* 科目名の配列 */
void init();
void regist(int, int, short);
void writeCourses();
void init(){
    FILE  *fStudent = fopen("student.txt", "r");
    FILE  *fCourse = fopen("course.txt", "r");
    FILE  *fRecord = fopen("record.txt", "r");
    int studentKey, courseKey, score;
    while(fscanf(fCourse, "%d", &courseKey) != EOF){
        fscanf(fCourse, "%s", courseName[courseKey]);
    }
    while(fscanf(fStudent, "%d", &studentKey) != EOF){
        fscanf(fStudent, "%s", student[studentKey].studentName);
        student[studentKey].rFirstCourse = NULL;
    }
    while(fscanf(fRecord, "%d %d %d", &courseKey, &studentKey,
                                               &score) != EOF){
        regist(courseKey, studentKey, (short)score);
    }
    fclose(fStudent);
    fclose(fCourse);
    fclose(fRecord);
}



void writeCourses(){
    FILE *fOutput = fopen("output.txt", "w");
    struct RECORD *p;
    int i; 
    for (i = 0; i < NUM_STUDENT; i++){
        fprintf(fOutput, "%05d %-24s ", i, 
                             student[i].studentName);
        p = student[i].rFirstCourse;
        while(p != NULL){
            fprintf(fOutput, "%-24s %3d ",  );
            p = p->rNextCourse;
        }
        fprintf(fOutput, "\n");
    }
    fclose(fOutput);
}

設問1 プログラム中の に入れる正しい答えを, 解答群の中から選べ。

a に関する解答群

ア &p     イ &p++     ウ NULL     エ p     オ p++

b に関する解答群

ア &courseName     イ *courseName[courseKey]

ウ courseName       エ courseName[courseKey]

オ p->rNextCourse->courseName

c に関する解答群

ア &p->courseName, &p->score    イ &p->courseName, p->score

ウ *p->courseName, *p->score        エ *p->courseName, p->score

オ p->courseName, &p->score       カ p->courseName, *p->score

キ p->courseName, p->score

解答 a ←クリックすると正解が表示されます

解答 b ←クリックすると正解が表示されます

解答 c ←クリックすると正解が表示されます

基本情報技術者試験


設問2 図1に例示した履修科目成績一覧において,科目名の出力順として正しい答えを, 解答群の中から選べ。

解答群

ア 科目キーの値が小さい科目ほど先に出力される。

イ 科目キーの値が小さい科目ほど後に出力される。

ウ 先に関数 regist で登録した科目ほど先に出力される。

エ 先に関数 regist で登録した科目ほど後に出力される。

オ 履修者数の少ない科目ほど先に出力される。

カ 履修者数の少ない科目ほど後に出力される。

解答 ←クリックすると正解が表示されます

基本情報技術者試験


設問3 次の記述中の に入れる正しい答えを, 解答群の中から選べ。

図1に例示した履修科目成績一覧において,得点の降順に出力されるように,関数 regist の α β を次のとおりに変更した。

なお, には正しい答えが既に入っているものとする。

処置 プログラムの変更内容
α を置換
struct RECORD *p;
struct RECORD *q;
β を置換
q = student[studentKey].rFirstCourse;
if () {
  p->rNextCourse = q;
  student[studentKey].rFirstCourse = ;
} else {
  while(){
    q = q->rNextCourse;
  }
  p->rNextCourse = q->rNextCourse;
  q->rNextCourse = ;
}

解答群

ア q != NULL && q->score < s

イ q != NULL && q->score > s

ウ q == NULL || q->score < s

エ q == NULL || q->score > s

オ q->rNextCourse != NULL && q->rNextCourse->score < s

カ q->rNextCourse != NULL && q->rNextCourse->score > s

キ q->rNextCourse == NULL || q->rNextCourse->score < s

ク q->rNextCourse == NULL || q->rNextCourse->score > s

解答 d ←クリックすると正解が表示されます

解答 e ←クリックすると正解が表示されます


[←前の問題] [次の問題→] [問題一覧表] [分野別] [基本情報技術者試験TOP ]