平成21年 秋期 基本情報技術者試験 午後 問9、C言語
- 2016/11/07
- 12:31
問題文、解答、解説の順で掲載しております。
無料から学べる講座
http://ai-light.com/itkeiei/
ニコニコチャンネル
http://ch.nicovideo.jp/ai-light
YouTubeチャンネル
https://www.youtube.com/user/ailightcom
Access・Excel倶楽部
http://ai-light.com/accessclub/
株式会社アイライト公式HP
http://www.ai-light.com/
(Access・Excelでシステム開発会社を探されている法人様はこちら)
***********************************************************************************************************
次のCプログラムの説明及びプログラムを読んで,設問1,2に答えよ。
〔プログラムの説明〕
C言語では整数型の変数に格納できる値には上限がある。これを超える正の整数 (以下,正の多倍長整数という)の入出力と加算を行うプログラムである。
(1) 正の多倍長整数は,次に示す MP型の構造体を用いて表現する。
typedef struct{
int length;
long data[ARRAY_MAX];
}MP;
正の多倍長整数を,下位から9けたずつに切り分けて,
構造体MPのメンバである配列dataの要素番号の小さい方から順番に値を格納する。 例えば46284059827463859201283844157134007652918723147641 という整数の場合, 図のとおりになる。

構造体のメンバー length には,実際に値を格納した要素数を入れる。図の場合は6である。
(2) 関数の仕様は,次のとおりである。
void set(MP *num, const char str[]);
引数: num MP 型の構造体で表現された多倍長整数
str 文字列で表現された多倍長整数であって,1~9の数字で始まる。
機能:文字列で与えられた多倍長整数strを変換して,MP型の構造体numに、格納する。numのメンバdataは,変換後の数値を格納するのに十分な要素数が 確保されているものとする。
返却値:なし
void print(const MP *num);
引数: num MP 型の構造体で表現された多倍長整数
機能:多倍長整数を出力する。
返却値:なし
void add(const MP *a, const MP *b, MP *c);
引数:a, b, c MP型の構造体で表現された多倍長整数であり,c は,a 及び b ではないものとする。
機能:二つの多倍長整数a,bの和を多倍長整数cに格納する。cのメンバdataは,加算処理を行うのに十分な要素数が確保されているものとする。
返却値:なし
(3) 次のライブラリ関数を用いる。
size_t strlen(const char *s);
機能:s が指す文字列の長さを計算する。
返却値:終端を示すナル文字に先行する文字の個数を返す。
〔プログラム〕
#include
#include
#define ARRAY_MAX 100
#define NUM_DIGIT 9
#define NUM_DIGIT_TH_POWER_OF_TEN 1000000000
typedef struct{
int length;
long data[ARRAY_MAX];
}MP;
void set(MP*, const char[]);
void print(const MP*);
void add(const MP*, const MP*, MP*);
/* 文字列から多倍長整数を扱う構造体に変換 */
void set(MP *num, const char str[]){
int str_idx = strlen(str) - 1;
int num_idx = 0;
int i;
long mul;
while( { a } ){
num->data[num_idx] = 0;
mul = 1;
for(i = O; { b } ; i++){
num->data[num_idx] += mul * (str[str_idx--]‐'0');
mul { c } ;
}
num_idx++;
}
num->length = num_idx;
}
/* 多倍長整数の出力 */
void print(const MP *num){
int i;
printf("%ld", num->data[num->length - 1]);
for( { d } ){
/* ゼロ詰めして必ず9けたを表示する。 */
printf("%09ld", num->data[i]);
}
printf("\n");
}
/* 二つの多倍長整数の加算 */
void add(const MP *a, const MP *b, MP *c){
int i;
int i_max;
if(a->length > b->length){
i_max = a->length;
}else{
i_max = b->length;
}
c->data[0] = 0;
for(i = 0; i < i_max; i++){
if(i < a->length) c->data[i] += a->data[i];
if(i < b->length) c->data[i] += b->data[i];
if(c->data[i] >= NUM_DIGIT_TH_POWER_OF_TEN){ ←―α
c->data[i + 1] = 1; ←―β
c->data[i] -= NUM_DIGIT_TH_POWER_OF_TEN;
}else{
c->data[i + 1] = 0;
}
}
if(c->data[i] == 0){
c->length = i;
}else{
c->length = i + 1;
}
}
設問1 プログラム中の { } に入れる正しい答えを,解答群の中から選べ。
a に関する解答群
ア str_idx != 0 イ str_idx < 0 ウ str_idx <= 0
エ str_idx > 0 オ str_idx >= 0
b に関する解答群
ア i < NUM_DIGIT
イ i < NUM_DIGIT && str_idx <= 0
ウ i < NUM_DIGIT && str_idx >= 0
エ i < NUM_DIGIT || str_idx <= 0
オ i < NUM_DIGIT || str_idx >= 0
c に関する解答群
ア %= 10 イ *= 10 ウ += 10
エ -= 10 オ /= 10
d に関する解答群
ア i = 0; i <= num->length - 1; i++
イ i = 0; i <= num->length - 2; i++
ウ i = num->length - 1; i >= 0; i--
エ i = num->length - 2; i >= 0; i--
設問2 プログラムの動作について, 次の記述中の { } に入れる正しい答えを解答群の中から選べ。
関数 add を用いて以下の (1) に示す二つの多倍長整数を加算する場合, プログラム中のα部分は { e } 回実行され, β部分は { f } 回実行される。 また,以下の (2) に示す二つの多倍長整数を加算する場合, β部分は { g } 回実行される。
e ~g に関する解答群
ア 0 イ 1 ウ 2 エ 3
オ 4 カ 5 キ 6 ク 7
***********************************************************************************************************
無料から学べる講座
http://ai-light.com/itkeiei/
ニコニコチャンネル
http://ch.nicovideo.jp/ai-light
YouTubeチャンネル
https://www.youtube.com/user/ailightcom
Access・Excel倶楽部
http://ai-light.com/accessclub/
株式会社アイライト公式HP
http://www.ai-light.com/
(Access・Excelでシステム開発会社を探されている法人様はこちら)
***********************************************************************************************************
********************************************************************************
設問1
答 aオ 答 bウ 答 cイ 答 dエ
設問2
答 eオ 答 fイ 答 gエ
参考:平成21年 秋期 基本情報技術者試験 午後 問09
******************************************************************
解説
#include
は、入出力に関する関数が定義されている。本問題ではprintfなどの関数が該当する。
#include
は、文字列操作に関する関数が定義されている。本問題ではstrlenなどの関数が該当する。
#define ARRAY_MAX 100
定数を定義している。
ここでは、"100"をARRAY_MAXと定義している。
struct{
int length;
long data[ARRAY_MAX];
};
構造体の定義をしている。この構造体は、lengthとdata[]という変数を持っている。
typedef
・・・・
MP;
既存の型に新しい名前を付けることができる。ここでは、構造体名をMPと定義している。
strlen(str)
strの文字列の長さを取得している。本問の図では、"50"となる。str_idxは、文字列数に"1"を引いた数をセットしている。上から順にプログラムを追ってみていく場合に、ここではstr_idxが何を表しているかわからない。もう少し、プログラムを読み進める必要がある。
while( { a } )
ここだけでは、{ a }に入るものは何かわからない。引き続き、プログラムを読み進めるしかない。
num->data[num_idx] = 0;
numはポインタの構造体である。ポインタの構造体の場合、構造体の要素を示す場合には"->"を使う。
for(i = O; { b } ; i++)
ここだけでは、{ b }に入るものは何かわからない。さらに、プログラムを読み進める。
num->data[num_idx]
num->data[]には問題文の説明より図の例では、次のようなデータをセットする必要がある。
num->data[0]="723147641"
num->data[1]="7652918"
num->data[2]="844157134"
num->data[3]="859201283"
num->data[4]="59827463"
num->data[5]="46284"
num->data[num_idx]で、最初はnum_idxに"0"がセットされている。
num->data[num_idx] += mul * (str[str_idx--]‐'0')なので、、num->data[0]に何らかと値をセットしようとしていることがわかる。
str_idxは図の例では"49"となる。
str[str_idx--]は、まずstr[str_idx]をしてから"-1"する。
str[49]には、図の例では文字列のもっとも右側の数値である"1"がセットされる。
strはchr型(文字型)となっている。‐'0'するのは文字コードの引き算をすることで、
文字コードから数値に変換している。
以上より、
num->data[num_idx] += mul * (str[str_idx--]‐'0');
で、num->data[0]から順に、文字列の一番右側からセットしていこうとしていることが
わかる。
mul { c } ;
では、解答は*=10となり、イとなる。
mul *=10 は
mul =mul*10のことで、
mul=1のとき、mul=10となり、
さらにmul=10のとき、mul=100となり
さらにmul=100のとき、mul=1000となる。
つまり、この式で、mulがカウントアップしていく形となっている。
よって、
num->data[num_idx] += mul * (str[str_idx--]‐'0')の部分は次のような処理となる。
1回目のループで
num->data[0]="1"
がセットされる。
2回目のループで
num->data[0]=10*4
となり、num->data[0]=41となる。
3回目のループで
num->data[0]=100*6
となり、num->data[0]=641となる。
{ b }
は、ループの終了条件である。
i
str_idxは、文字列の配列数を表しており、配列数は"0"以上の数値であることから解答はウかオとなる。data[5]のとき、dataの最大値9になる前にセットする文字列がなくなることから、str_idx>=0は必須の条件となる。よって解答はウとなる。
{ a }
解答群をみるとstr_idxの条件のみとなっている。str_idxは文字列の配列数を表しているから、str_idx>=0となる。
以上よりプログラムは上から順に解読していかなければならないが、本問題のようにある程度プログラムを我慢して読み進めないとプログラムは解読できない。また、問題も上から順に解けるわけではないことに注意する。
{ d }
問題文より図の場合にはnum->lengthは"6"が入っている。
num->dataはnum->data[0]からnum->data[5]となるので、
printf("%ld", num->data[num->length - 1])で"1"を引いている。
num->dataは配列の要素数が大きいものから表示している。
また、num->data[num->length - 1]はすでに表示済となるので、if文の初期条件は、
i = num->length - 2となる。
さらにデータは配列の要素数の大きいものから小さいものにかけて表示するので、繰り返し条件はi--となる。
よって、解答はエとなる。
{ e }
(1)の場合、i_maxが"4"になる。よってαは4となり、解答はオとなる。
{ f }{ g }
βはdata[]が9桁を超えた場合に実行される。
よって、(1)の上部の数列と下部の数列が9桁を超えるのは、1回なので、解答はイとなる。
同様に(2)の上部の数列と下部の数列が9桁を超えるのは、3回なので、解答はエとなる。
***********************************************************************************************************
無料から学べる講座
http://ai-light.com/itkeiei/
ニコニコチャンネル
http://ch.nicovideo.jp/ai-light
YouTubeチャンネル
https://www.youtube.com/user/ailightcom
Access・Excel倶楽部
http://ai-light.com/accessclub/
株式会社アイライト公式HP
http://www.ai-light.com/
(Access・Excelでシステム開発会社を探されている法人様はこちら)
***********************************************************************************************************
- 関連記事
-
- 平成7年秋期第二種情報処理技術者試験午後問7、C言語 (2017/03/29)
- 平成21年 秋期 基本情報技術者試験 午後 問9、C言語 (2016/11/07)
- 平成21年 春期 基本情報技術者試験 午後 問9、C言語 (2016/11/02)