応用情報処理技術者試験の対策サイトです。 応用情報処理技術者試験の午前問題を中心とした基礎用語の解説を中心に掲載します。書き始めたばかりなので、内容はまだまだ不十分です。
カテゴリ:

13.実際の設定 > 13.2 C言語ではこうなります

配列を作ると、メモリにアドレスが確保されます。その様子をプログラムで実行します。
#include <stdio.h>
void main() {
    int A[100];  // 配列変数Aを定義。保存可能個数は100個でA[1]-A[100]を使用可能。
    int k;// 整数型の変数kを定義
    // kを1から100まで、1ずつ増やす(k++)
    for (k = 1; k <= 100; k++) {
        A[k] = k; 
        printf("A[%d]_add:%p\n",k,&A[k]); //A[k]のアドレスを表示
    }
}

結果は、以下のようになります。

c:\work>pg1.exe
A[1]_add:0028FDA0
A[2]_add:0028FDA4
A[3]_add:0028FDA8
A[4]_add:0028FDAC
A[5]_add:0028FDB0
A[6]_add:0028FDB4
A[7]_add:0028FDB8
・・・・
続きを読む

■H25春
問7 配列Aに対して次の手続を実行して,2≦k≦100である素数kだけを全て出力したい。a,b,cに入るループの初期値,終値,増分として,適切な組合せはどれか。

for k = 2 to 100 step 1:
  A[k] = 1;
for m = 2 to 10 step 1:
    for k =[   a   ] to [   b   ] step [   c   ]:
   A[k] = 0;
for k = 2 to 100 step 1:
  if A[k]≠0:
   print k;

H25h-問7
【正解】イ
実際のプログラムの例は以下
#include<stdio.h>   // stdio.h(標準入出力を行うための関数が定義されたファイル)を読み込む
// main関数。引数は取らない。処理後に値を返さない
void main() {
    int A[101];    // 配列変数Aを定義。保存可能個数は101個でA[0]-A[100]を使用可能。
    int k, m;  // 整数型の変数kとmを定義
    // kを2から100まで、1ずつ増やす(k++)
    for (k = 2; k <= 100; k++) {
        A[k] = 1;  // A[2]-A[100]をすべて1にしている
    }
    // 2の倍数-10の倍数をリストから消していく
    for (m = 2; m <= 10; m++) { // mを2から10まで1ずつ増やす
        for (k = 2*m; k <= 100; k += m) {
            // kを2mから100までmずつ増やす
            // つまりkは2m, 3m, 4m,・・・と変化
            A[k] = 0;  // kはmの倍数=素数ではないから0にする
        }
    }
    for (k = 2; k <= 100; k++) { // kを2から100まで1ずつ増やす
        if (A[k] != 0) {  // A[k]が0でない、つまりkが素数なら
            printf("%d,", k);  // kを表示
        }
    }
}
【処理の解説】
・エラトステネスのふるい法を使って素数を求めています。
・変数Aは、0か1の値になるが、A[k]=0なら非素数、A[k]=1なら素数(処理の途中では「素数の可能性」)
・まず2から100をすべて素数かもしれないリストに入れる
   (k=2-100についてA[k] = 1)
・素数とは「約数として自分と1だけもつ」ことから、「何かの倍数であれば素数ではない」という考えで、倍数をすべて消していく。具体的にはA[k] = 0

■H25秋
問8 再帰的に定義された手続procで,proc(5)を実行したとき,印字される数字を順番に並べたものはどれか。
     proc(n)
      n=0ならば戻る
      そうでなければ
      {
       nを印字する
       proc(n-1)を呼び出す
       nを印字する
     }
     を実行して戻る

ア 543212345
イ 5432112345  
ウ 54321012345  
エ 543210012345

【正解】イ

実際のプログラムは以下
#include<stdio.h> // stdio.h(標準入出力を行うための関数が定義されたファイル)を読み込む

// proc関数。整数を一つ(int n)受け取って処理を行い、処理後に値は返さない(void)
void proc(int n) {
    if (n == 0) // もしnが0なら
        return; //   何もせず戻る
    else        // そうでなければ(nが0以外なら)
    {
        printf("%d", n); // nを表示
        proc(n-1);       // proc(n-1)を実行
        printf("%d", n); // nを表示
    }
}

// main関数。引数は取らない。処理後に値を返さない
void main() {
    proc(5);
}


補足解説
  proc(n)の流れは
    ・nを表示
    ・proc(n-1)を実行
    ・nを表示
  の3段階。
 
  したがって、proc(5)を呼び出すと、
    ・5を表示
    ・proc(4)を実行
    ・5を表示
 
  proc(4)の処理は
    ・4を表示
    ・proc(3)を実行
    ・4を表示
  

  これを続けていくと、
    ・5を表示
     ・4を表示
      ・3を表示
       ・2を表示
        ・1を表示
         ・proc(0)を実行
        ・1を表示
       ・2を表示
      ・3を表示
     ・4を表示
    ・5を表示

  proc(0)は何もせずにreturnするため、
  最終的に、
      ・5を表示
     ・4を表示
      ・3を表示
       ・2を表示
        ・1を表示
        ・1を表示
       ・2を表示
      ・3を表示
     ・4を表示
    ・5を表示
  という処理になる。

与えられたa,bは正の整数です。a,bの最大公約数を求めます。
フローチャートは、情報処理技術者試験(H29春AP問6)にあります。

終了時にxに格納されているものが、最大公約数です。
※mod(x,y)はxをyで割った余りです。
H29h-問6
たとえば、以下の数字で考えます。
x=20、y=25

■ループ1:t=20、x=25、y=20
■ループ2:t=5、x=20、y=5
■ループ3:t=0、x=5、y=0 ←ループ終了

終了時にはxに、a(20)とb(25)の最大公約数である5が入ります。

プログラム
実際にCでプログラムを書いてみると、以下のようになります。
#include <stdio.h>

//mod関数("x"を"y"で割った余りを計算する)
int mod(int x, int y)
{
 //"%"は余りを計算する演算子
 return x%y;  //"x"を"y"で割った余りを返す
}

//main関数
void main(){
 int x, y;
 int t;   // 余りを入れる

 //標準入力からxとyの値を取得
 printf("整数aを入力してください:");
 scanf("%d", &x);
 printf("整数bを入力してください:");
 scanf("%d", &y);

 //while文で"y"が0以外の場合はループ1を実施
 while(y!=0){
  t = mod(x, y);  //定義したmod関数の戻り値を"t"に代入
  x = y;  //"y"の値を"x"に代入
  y = t;  //"t"の値を"y"に代入
 }

 printf("x=%dです\n", x);
}

プログラム(xとyの入力チェックを含めた少し詳細なもの)
#include <stdio.h>

int mod(int x, int y)
{
 return x%y;
}

void main(){
 int x, y;
 int t;

 printf("input x:");
 if(scanf("%d", &x)!=1){  //数値の取得に失敗した場合
  printf("入力エラー\n");
  return;  //プログラムの途中終了
 }

 if(x<=0){  //xが正の整数で無い場合
  printf("数値が不正です\n");   //プログラムの途中終了
  return;
 }

 printf("input y:");

 if(scanf("%d", &y)!=1){
  printf("入力エラー\n");
  return;
 }

 if(y<=0){
  printf("数値が不正です\n");
  return;
 }

 while(y!=0){
  t = mod(x, y);
  x = y;
  y = t;
 }

 printf("x=%dです\n", x);

}

fact(n)は,非負の整数nに対してnの階乗を返す。
たとえば、fact(4)=4×3×2×1=24 です。これを求めるプログラムを書いてみます。

1.再帰的に書く場合
#include <stdio.h>

//fact関数
int fact(int n)
{
 if(n==0){  //"n"が0の場合
  return 1;  //1を返す
 }
 else{//"n"が0以外の場合
  //"n-1"を引数としてfact関数の再帰呼び出し
  return n*fact(n-1);  //"n"と戻り値の積を返す
 }
}

//main関数
void main(){
 int n;  //"n"をint型変数で定義
 //標準入力からnの値を取得
 printf("nの値を入力してください:");
 scanf("%d", &n);   //scanfを利用して整数入力させ、nに入れる

 //fact関数を階乗の結果を呼び出して表示する
 printf("fact(n)=%dです\n", fact(n));
}
ああ

2.再帰的に書かない場合
#include <stdio.h>

void main(){
 int n; //ある整数n
 int fact = 1; //nの階乗。最初は1とする
 int i; //ループに使う値
 
 // 標準入力からnの値を取得
 printf("nの値を入力してください:");
 scanf("%d", &n);   //scanfを利用して整数入力させ、nに入れる
  
 //階乗の計算。iを1から順にnになるまで掛け算する
 for(i=1; i<=n; ++i) {
     fact = fact * i;
  }; 

 //結果を表示する
 printf("%dの階乗は、%dです\n",n,fact);
}
 

if文とelseを使って、条件分岐をする。

◆シンプルにプログラムを書いてみた。
正の整数を入力してもらう。xが0以下の場合はエラーとして強制終了する。
#include <stdio.h>

void main(){
 int x;

 printf("正の整数xの値を入力してください:");
 scanf("%d", &x);   //scanfを利用して整数入力させ、xに入れる

 if(x<=0){  // "x"が0以下の場合
  printf("正の整数ではありません\n");
  return;  //プログラムの途中終了
 }
 else{
  printf("入力された値は%dです。\n", x); 
 } 
}

※今回の場合、else {}でくくらなくてもいい。

scanf(スキャンエフ)を使って、キーボード入力。この場合は、整数値をxに入れる
 scanf("%d",&x);

◆1.シンプルにプログラムを書いてみた。
整数入力としてxに値を入れて、それを表示する
#include <stdio.h>

void main(){
 int x;
 printf("xの値を入力してください:");
 scanf("%d", &x);   //scanfを利用して整数入力させ、xに入れる
        //%dは整数の場合で、%fは浮動小数点、%cは文字などと決められている
 printf("入力された値は%dです。\n", x);   // "\n" は改行コード。%dにxの値が入る。
}

※戻り値がなく、単に表示するだけなのでvoidを使っている。
※実行してきちんと動くと、うれしい。

◆2.数字が入力されているかをチェック
文字ではなく数字が入力されているかのチェックし、数字ではない場合には「入力エラーです」と表示する場合は次のようになります。
#include <stdio.h>

void main(){
 int x;
 printf("xの値を入力してください:");

// 文字ではなく数字が入力されたかのチェック。scanfは取得に成功したデータの数を返す。よって、値が1でなければエラー
if(scanf("%d", &x)!=1){ //数値の取得に失敗した場合
  printf("入力エラーです\n");
  return;  //プログラムの途中終了  
 }
 
 printf("入力された値は%dです。\n", x);  
}


プログラムを書いてみた。
printfを使って、「こんちくは」と表示する

#include<stdio.h>

void main(){

 printf("こんちくは");

}

戻り値がなく、単に表示するだけなのvoidを使っている。
※実行してきちんと動くと、うれしい。

H18春FE午前
問12 空の状態のキューとスタックの二つのデータ構造がある。次の手続を順に実行した場合,変数xに代入されるデータはどれか。ここで,
データyをスタックに挿入することをpush(y),
スタックからデータを取り出すことをpop(),
データyをキューに挿入することをenq(y),
キューからデータを取り出すことをdeq() ,
とそれぞれ表す。

push(a)
push(b)
enq(pop())
enq(c)
push(d)
push(deq())
x←pop()

ア a  イ b  ウ c  エ d
正解は、イのbです。

実行結果を先に書きます。実際のプログラムは後半に記載します。
c:\pg>stack.exe
初期状態
スタックの状態:
キューの状態:

push(a) データ a をスタック(の最後)に挿入
スタックの状態:[a]
キューの状態:

push(b) データ b をスタック(の最後)に挿入
スタックの状態:[a][b]
キューの状態:

enq(pop()) スタック(の最後)からデータを取り出して、それをキュー(の最後)に挿

スタックの状態:[a]
キューの状態:[b]

enq(c) データ c をキュー(の最後)に挿入
スタックの状態:[a]
キューの状態:[b][c]

push(d) データ d をスタック(の最後)に挿入
スタックの状態:[a][d]
キューの状態:[b][c]

push(deq()) キュー(の先頭)からデータを取り出して、スタック(の最後)に挿入
スタックの状態:[a][d][b]
キューの状態:[c]

x = pop() スタック(の最後)からデータを取り出したデータを x とする
x の値: b
スタックの状態:[a][d]
キューの状態:[c]
続きを読む

このページのトップヘ