コンピュータ基礎および演習Iの模範解答

本日の内容

    1. 第二回
    2. 第三回
    3. 第四回
    4. 第五回
    5. 第六回
    6. 第七回
    7. 第八回
    8. 第九回
    9. 第十回
    10. 第十一回

1. 第二回

コンピュータの電源の入れ方、切り方。

解答

電源の入れ方:
  1. AC アダプタを接続する。(接続せずに電源を入れると、バッテリが弱っている場合、正常に起動しない場合がある)
  2. 本体背面のメインスイッチが入っていることを確認する。
  3. 本体のディスプレイを上げ、本体右奥の電源スイッチを押す。
電源の切り方
  1. Alt+F4 で、起動しているアプリケーションソフトを全て終了させる。
  2. スタート→Windowsの終了を選び、終了を選び OK を押す。

ハードディスクの総容量、ハードディスクの空き容量、CPU の名前、メモりの容量、バッテリの充電状況

解答

ハードディスクの総容量、空容量の調べ方
マイコンピュータを開き(右ボタンを押し、「開く」を選ぶ)、 C ドライブを右クリックすると左側に表示される。
CPU の名前、メモりの容量
マイコンピュータを右クリックし、プロパティを選ぶと、表示される。
バッテリの充電状況
画面右下のバッテリのマークを右クリックし、プロパティを選ぶ。

次の行為をして良いか悪いか、利用許諾条件を読んで答えなさい。

  1. ノートパソコンの貸し借り
  2. Windows の CD-ROM の貸し借り
  3. Windows のソフトウェアの開発
  4. Windows の内部解析
  5. Windows のバックアップ

要点

著作権法は著作者の人格権と財産権を保護して文化の発展を図るのが目的である。 この法律では、公表権、複製権、同一性保護権など著作物に関する様々な権利の保護がうたわれているが、その一方、ソフトウェアの使用権や私的なコピーについては制限を与えてない。 但し、私的でないコピーや貸与権は制限されている(レンタルソフトウェアショップは著作権者が許可しないため、開けない)。 ところで、一般的なソフトウェア会社は、この利用権や私的なコピーにも制限を加えようとする。 そのため、一般的な市販ソフトは使用する際に、包装を開けると使用許諾契約が結ばれるようになっている。 使用許諾契約には、著作権法で禁止されてない、私的コピーの制限や、使用形態の制限などが書かれている。 (マイクロソフト社のライセンスは最も厳しいものの一つであるが、一方、過去、ボーランド社は「本と同様に扱えば良い」という寛大なライセンスであったこともあった)

  1. ノートパソコンの貸し借り
    ソフトウェアの貸し借りについて、「レンタル」という項目で制限されているので、Windows などのソフトウェアを全てを消去した状態でのみ貸与可能。
  2. Windows の CD-ROM の貸し借り
    上記項目と同様に貸与できない。
  3. Windows のソフトウェアの開発
    特に規定されてないので自由に行って良い。
  4. Windows の内部解析
    「リバースエンジニアリング、逆コンパイル、逆アセンブルの制限」という項目が使用許諾条件にあるので、不可
  5. Windows のバックアップ
    使用許諾条件により、一部のみ作成可能。(バックアップが破損することなどを考えると不当な制限に思える)

ハードディスクの内容が全て消えたとき、修復する方法を書きなさい。

解答

リカバリディスクを入れ、電源を入れ、画面の指示に従う。

2. 第三回

[演習] MS-DOS プロンプトを使用してみる

MS-DOS プロンプトで次のコマンドを入力し、結果がどうなったか示しなさい。

解答

  1. cd
    \Windows が表示される。
  2. rem abc
    何も表示されない。
  3. echo abc
    abc が表示される。
  4. cd \windows
    \windows が表示される。
  5. type licence.txt
    使用許諾条件が表示される。
  6. sol
    (インストールされていれば)ソリティアというゲームが動く
  7. exit
    MS-DOS プロンプトが消える。

[演習] 次の構造を持つように C ドライブにフォルダを作りなさい。

figure of exercise

  1. mkdir \d
  2. mkdir \d\e
  3. mkdir \d\f
  4. mkdir \d\e\g
  5. mkdir \d\e\h

3. 第四回

ワードの演習

(略)

「キーボードやマウスに代る次世代入力方式の可能性について」

要点

入力の意義を考え、適切な入力方式を提案する。 「始めに入力方式ありき」的な書き方は説得力が薄い。 (1)現状分析(2)必要な入力内容(3)それに適した方式の提案の順に書くと良い。 (このように、技術的な文章は問題点を挙げて解決していく方針で書くと良い)

解答例

現在、コンピュータの入力方式として代表的なものは、キーボードとマウスである。 ここではそれに代る次世代入力方式について考えてみたい。

まず、現状について考える。 現在、キーボードとマウスが使われているが、その用途は、キーボードは主に文章の入力に、マウスは位置の指示に使われている。 つまり、現状のコンピュータの入力は、文章の入力と、位置の指示の二種類に分けられ、それぞれ、キーボードとマウスが分担しているという形態になっている。

では、まず、位置を指示する方式について考えてみよう。 位置を指示するのに最も適しているのは、実際の画面の位置を直接指示することである。 これに関しては、パームコンピュータなどの携帯端末では既に利用されている。 また「ライトペン」や「タッチパネル」なども利用されている。 これらの利用実績はそこそこあるが、マウスほど普及していない。 それは、恐らくマウスの単純さやコストによるものであろう。 一方、マウスの代用品として考えられているものとして、ノートパソコンに採用されている、タッチパッド、スティック、トラックボールなどがある。 これらは一長一短あり、どれかが飛び抜けて優れているわけではない。 タッチパッドは指を滑らすことに慣れなければならない。 スティックは力の加減でポインタの動く速さをコントロールするため、力の加減になれなければならない。 トラックボールは指を曲線的に動かす必要があるため、微妙なコントロールには慣れが必要である。 但し、どれも製品を小型化でき、耐水性や無重力でも利用可能などの付加価値も生じる。 さて、私が思う次世代の位置の指示方法であるが、今挙げた様々な装置の持つ長所を持つようなデバイスの開発である。 これはなにも難しいことではなく、複数の位置指示デバイスを融合させたものである。 既にマウスにダイアルを付けたものが販売されているように、時代はもうその方向に向っているのではないかとも思われる。

一方、文章の入力であるが、これは、手書き入力、音声入力とキーボードの比較になるであろう。 手書き入力、音声入力とも、長所は習熟の必要がないことであるが、短所として、スピードがキーボードより遅いことと、機械の認識率が 100% でないことが挙げられると思う。 キーボードは習熟が必要ではあるが、人間の思考の内容をコンピュータに伝えるには最も速いものであり、また、人間が意図した内容を確実にコンピュータに伝えることができる。 そのため、単純に考えれば、どの長所を生かすかという話に収束しそうである。 しかし、ここで発想を変えてみよう。 習熟が必要なことと、認識率が低いこととどちらが我慢できるかということである。 つまり、「習熟が必要な手書き入力」、「習熟が必要な音声入力」というものが開発できた時、もし認識率が上れば十分実用的なのではないかと思われる。 実際、パームコンピュータで既に採用されている手書き入力は、習熟が必要な特殊な書き方をおぼえることにより、識字率を上げてる。 音声入力に関しても同様の考え方ができるのではないだろうか? つまり、コンピュータへの入力において、コンピュータが流暢な日本語を認識する必要はないであろう。 人間がコンピュータが理解しやすいちょっと変な日本語を人間が喋ればコンピュータの認識率が上るであろう。 具体的な方法としては、「かけ声」や「節回し」などが考えられる。 但し、これは人前でやっても恥ずかしくないような方法でないと普及しないと思われる。 DJ やラッパーなどはかっこよくかけ声や節回しをするので、彼らのは参考にならないだろうか?

さて、いままで現状のコンピュータの操作である「位置の指示」と「文章の入力」に関する提案を行ってきたが、ここでコンピュータの操作自体を新しくすることを考える。 つまり、今のコンピュータの操作に対して自然な拡張を考えてみる。 自然な拡張として提案するのは、オブジェクト指向的な拡張である。 オブジェクト指向的とは、コンピュータで操作される対象をすべて個々の「オブジェクト」として捉えることである。 個々のオブジェクトは「メッセージ」を送ることにより操作されることになっている。 このような考え方をした場合、コンピュータの操作は特定のオブジェクトにメッセージを送ることにより実現されると考えることができる。 特定のオブジェクトを指示するには、そのオブジェクトに対応するアイコンやウィンドウで表示させ、「位置の指示」を行えばよい。 問題はメッセージをどう送るかである。 オブジェクトに与えるメッセージの種類はそれほど必要ないので、キーボードから文章を送るのは非効率的である。いくつかのメッセージをなんらかの入力方式により送ることができることが望ましい。 そこで、提案するのは「ゼスチャー」である。利用者がなんらかの特定の動作をするとそれをメッセージとして認識するようにするのである。 これは一部は実際にもう行われている。 一つは「ダブルクリック」である。これは「開く」という意味を持つ「ゼスチャー」であり、この「開く」というメッセージが送られたオブジェクトは開かれる。 もうひとつはカシオなどが採用している入力方式である。 これは、通常は位置を指示するためのパッドに大きく英字一文字のサインを送ると特定の動作をさせることができるというものである。 現在、Windows などを利用するアプリケーションソフトウェアは、ほぼ「開く」「閉じる」「カット」「コピー」「ペースト」などをメニュー項目としてもっている。 これらを適当な動きなどで指示すれば、現状の「右クリック+メニュー選択」より効率的になる可能性がある。

以上、いくつかの観点から次世代入力方式についての提案を行った。 複合化した位置を指示する装置でゼスチャーを入力しながら、かけ声をかける様は次世代という感がする。 しかし一方正直なところ、子供の頃に観たロボットアニメなどの技を出す時に技の名前を言いながらボタンを押すシーンも浮んでくる。 実際あの方式が合理的だったかはわからないが、今回分析しながら提案した方式と計らずも一致してしまったのは面白いと思った。

4. 第五回

演習1

コンピュータプログラムのレポートを電子メールで提出するにはどう いう方法が望ましいか? 提出方法のマニュアルを書きなさい。

コンピュータのプログラムは通常テキストファイルなので、プログラム自身はそのまま 電子メールとして送ることは可能である。 従って単純にプログラムを提出するには、電子メールの一部にプログラムを張り込めば良い。

プログラムのファイル名を sample.c とした場合、以下がプログラムを送る手順である。

  1. メモ帳を立ち上げる。
  2. 「ファイル→開く」を指定し、「ファイルの種類」を「全てのファイル(*.*)」とし、sample.c を読み込む。
  3. 「編集→全てを選択」を選び、「編集→コピー」を選ぶ。
  4. メールソフトを立ち上げる。
  5. メールソフトで、「編集→貼り付け」でプログラムを貼り付ける。

Excel の演習

省略

5. 第六回

演習1

  1. 高校の後輩に対して、「大学に合格するにはどうすればよいか?」 書きなさい。
  2. 上記を書いた時に、読み易くするために気を付けた、文章の構成方 法を書き出しなさい。

要点

さまざまな要因を整理して簡潔に書くのが目的なので、箇条書きなどを利用する。

解答例

大学に合格するには……
事務的な手順
  1. 受験資格は、高校卒業または大験など卒業と同程度の学力を持つと認定されること。
  2. 共通テストの受験
  3. 二次試験の受験
学習する上での注意点
  1. 不得意科目の学力を伸ばすことを主眼に学習する。
  2. 得意科目はミスをしないような工夫をする。
  3. 定期的に模擬試験を受け、志望校が適切かどうかチェックする。
工夫したこと
  1. 事務的な内容と学習上の内容を分け、それぞれ箇条書きにした。
  2. 様々な要因が考えられるが、それぞれ三項目に絞った。

演習2

次のプログラムを読んで、このプログラムが何をするか調べなさい。 そして、プログラムを実行するとどのような動作になるか書きなさ い。

/* This program prints "Hello World!". */
#include <stdio.h>
main(){
  printf("Hello World!\n");
}

解答

画面に「Hello World!」が書かれる。

演習4

このプログラムを改造して、「Hello New World!」を画面に出しなさい。

解答

#include <stdio.h>
main(){
  printf("Hello New World!\n");
}

演習5

次のプログラムを読んで、このプログラムが何をするか調べなさい。 そして、プログラムを実行するとどのような動作になるか書きなさ い。

解答

これは、二次方程式の解を求めるプログラムである。実行すると画面に次のように表示される。

 2.000000 x^2 + 3.000000 x + 1.000000 = 0
root1= -0.500000, root2= -1.000000
但し、このプログラムは、次の行が誤りである。
      zitsubu= -b/2/a; kyobu = sqrt(d)/2/a;
これは次のように変更する必要がある。
      zitsubu= -b/2/a; kyobu = sqrt(-d)/2/a;

(他の演習は省略)

6. 第七回

例題

  1. 次のプログラムがどのように動作するか予想しなさい。
  2. 次にプログラムを実際にコンパイルし、予想通り動作するか確かめなさい。
#include <stdio.h>
main(){
   int i;
   float a;
   i=1;
   i=i+1;
   a=0.314E1;
   printf("%d %f\n",i,a);
}

解答

2 3.140000

演習

  1. 二元連立一次方程式の解法を書きなさい。式は次の通りとし、与え られる値は a,b,c,d,e,f とする。
        a x + b y = e
        c x + d y = f
    
  2. C 言語で二元連立一次方程式を解くプログラムを書きなさい。

解答

    1. det = ad - bcとする。
    2. detが 0 でないとき、 x, y は次の式で得られる。
              ┌x┐     1  ┌  d  -b ┐┌ e ┐
              │ │ =  --- │        ││   │
              └y┘    det └ -c   a ┘└ f ┘
      
      従って、 x=(de-bf)/det, y=(-ce+af)/det である。
    3. det が 0 の時: a:b:e=c:d:f ならば ax+by=e を満たす全ての x, y、そうでなけ れば解無し。 なお、a:b:e=c:d:f は C 言語では判定できない。 a:b=c:d は、ad-bc=0 は既にわかっているので、 a:e=c:f を判定すれば良い。 つまり、af と ce が等しいかどうかを判定すれば良い。
  1. プログラムは次の通りである。
        #include <stdio.h>
        main(){
          float a,b,c,d,e,f,x,y;
          float det;
          a=1.0; b=2.0; c=3.0; d=4.0; e=5.0; f=6.0;
          det = a * d - b * c;
          if(det==0){
            if(a*f==c*e){
              printf("%f x + %f y = %f を満す全ての x, y\n",a,b,e);
            }else{
              printf("解なし\n");
            }
          }else{
            x=(d*e-b*f)/det;
            y=(-c*e+a*f)/det;
              printf("x = %f, y = %f\n",x,y);
          }
        }
    

7. 第八回

演習8-1

次のように定義されている配列 a の平均値を求めるプログラムを書きな さい。

int a[10]={4,5,3,1,7,8,9,2,0,6};

解答

#include <stdio.h>
main()
{
  int a[10]={4,5,3,1,7,8,9,2,0,6};
  int i,sum;
  float heikin;
  sum=0;
  i=0;
  while(i<10){
    sum=sum+a[i];
    i=i+1;
  }
  heikin=sum/10.0;
  printf("%x\n",heikin);
}

演習8-2

for 文を使用して、平均を求めるプログラムを書け

解答

#include <stdio.h>
main()
{
  int a[10]={4,5,3,1,7,8,9,2,0,6};
  int i,sum;
  float heikin;
  sum=0;
  for(i=0;i<10;i++){
    sum+=a[i];
  }
  heikin=sum/10.0;
  printf("%d\n",heikin);
}

演習8-3

1 から 100 までの数を画面に表示するプログラムを書け

解答

#include <stdio.h>
main()
{
  int i;
  for(i=1;i<=100;i++){
    printf("%d\n",i);
  }
}

演習8-4

標準偏差を求めるプログラムを書け

解答

#include <stdio.h>
main()
{
  int a[10]={4,5,3,1,7,8,9,2,0,6};
  int i,sum,dsum;
  float heikin,bunsan,hyouzyunhensa
  sum=0;
  dsum=0;
  for(i=0;i<10;i++){
    sum+=a[i];
    dsum+=a[i]*a[i];
  }
  heikin=sum/10.0;
  bunsan=dsum/10.0-heikin*heikin;
  hyouzyunhensa=sqrt(bunsan);
  printf("%f\n",hyouzyunhensa);
}

演習8-5

点数が配列に入っている時、偏差値を印刷するプログラムを書け

偏差値 = (値-平均)*10/標準偏差 + 50

解答

#include <stdio.h>
main()
{
  int a[10]={4,5,3,1,7,8,9,2,0,6};
  int i,sum,dsum,hensachi;
  float heikin,bunsan,hyouzyunhensa,
  sum=0;
  dsum=0;
  for(i=0;i<10;i++){
    sum+=a[i];
    dsum+=a[i]*a[i];
  }
  heikin=sum/10.0;
  bunsan=dsum/10.0-heikin*heikin;
  hyouzyunhensa=sqrt(bunsan);
  for(i=0;i<10;i++){
    hensachi=(a[i]-heikin)*10.0/hyouzyunhensa+50;
    printf("点数: %d  偏差値:%d\n",a[i],hensachi);
  }
}

演習8-6

文字列の先頭に空白がいくつあるかを数えるプログラムを書け

解答

#include <stdio.h>
main(){
  int i,num;
  char a[]="    This   is a   sample sentence.";
  printf("%s\n",a);
  i=0;
  while(a[i]==' '){
    i=i+1;
  }
  printf("There are %d spaces in front of the string.\n",i);
}

演習8-7

文字列に単語がいくつあるかを数えるプログラムを書け

解答

#include <stdio.h>
main(){
  int i,num;
  char privious;
  char a[]="    This   is a   sample sentence.";
  printf("%s\n",a);
  i=0;
  num=0;
  privious=' ';
  while(a[i]!='\0'){
    if(privious==' '){
      if(a[i]!=' '){num=num+1;}
    }
    privious=a[i];
    i=i+1;
  }
  printf("This string has %d words.\n",num);
}

8. 第九回

演習9-1

画面に abcdefg を印刷するプログラムを書け

解答

#include <stdio.h>
main(){
  printf("abcdefg\n");
}

演習9-2

整数型変数iは次のように定義されているとする。

int i=23;

画面にiの内容を表示するプログラムを書け。 但し、出力は次のように なるのが望ましい。

解答

The value of i is 23.
#include <stdio.h>
main(){
  int i=23;
  printf("The value of i is %d.\n",i);
}

演習9-3

浮動小数点型変数xは次のように定義されているとする。

float x=0.314E1;

画面にxの内容を表示するプログラムを書け。 但し、出力は次のように なるのが望ましい。

変数 x の値は 3.14000.

解答

#include <stdio.h>
main(){
  float x=0.314E1;
  printf("変数 x の値は %f.\n",x);
}

演習9-4

文字型変数cは次のように定義されているとする。

char c='a';

画面にcの内容を表示するプログラムを書け。 但し、出力は次のように なるのが望ましい。

文字変数 c の値は 'a' である。

解答

#include <stdio.h>
main(){
  char c='a';
  printf("文字変数 c の値は '%c' である。",c);
}

演習9-5

文字型の配列変数sは次のように定義されているとする。

char s[]="abcdefg";

画面にsの内容を表示するプログラムを書け。 但し、出力は次のように なるのが望ましい。

配列変数 s は文字列として abcdefg という値を持つ。

解答

#include <stdio.h>
main(){
  char s[]="abcdefg";
  printf("配列変数 s は文字列として %s という値を持つ。",s);
}

演習9-6

変数i の値が 0 より大きかったら画面に「正の値」、0 より小 さかった ら画面に「負の値」、 0 だったら「零」を表示するプログラムを書 きな さい。

(但し、あらかじめiには次のように値が代入されているとする。)

int i=3;

解答

#include <stdio.h>
main(){
  int i=3;
  if(i>0){
    printf("正の値\n");
  }else if(i<0){
    printf("負の値\n");
  }else{ /* i==0 */
    printf("零\n");
  }
}

演習9-7

あらかじめ浮動小数点の変数a, bには次のように値が与えられていると する。

float a=3.0;
float b=6.0;

このとき、a≠0であるとき、一次方程式

a x + b = 0

の解を求め表示せよ。

解答

#include <stdio.h>
main(){
  float a=3.0;
  float b=6.0;
  float x;

  x=-b/a;
  printf("%f\n",x);
}

演習9-8

あらかじめ浮動小数点の変数a, bには次のように値が与えられていると する。

float a=3.0;
float b=6.0;

この時、式

a x + b = 0

の解を求め表示せよ。但し、aが 0 であっても正しく解を表示できるよ うにせよ。

解答

#include <stdio.h>
main(){
  float a=3.0;
  float b=6.0;
  float x;

  if(a==0){
    if(b==0){
      printf("The equation %d x + %d = 0 holds for any x.\n",a,b);
    }else{
      printf("The equation %d x + %d = 0 can not hold for any x.",a,b);
      printf(" That is, this has no root.\n");
    }
  }else{
    x=-b/a;
    printf("The root of the equation %d x + %d =0 is %f\n",a,b,x);
  }
}

演習9-9

整数変数nは次のように値が代入されているとする。

int n=50;

このとき、画面に1からnまでを表示するプログラムを書け。

解答

#include <stdio.h>
main(){
  int n=50;
  int i;

  for(i=1;i<=n;i++){
    printf("%i\n",i);
  }
}

演習9-10

整数変数nは次のように値が代入されているとする。

int n=50;

このとき、画面に1からnまでの和、つまり

1+2+3+...+n

の値を表示するプログラムを書け。

解答

#include <stdio.h>
main(){
  int n=50;
  int i,sum;
  sum=0;
  for(i=1;i<=n;i++){
    sum+=i;
  }
  printf("%d\n",sum);
}

演習9-11

整数変数の配列に次のように値が代入されているとする。

int a[10]={5,4,2,0,1,9,7,3,8,6};

この時、画面に a[0] から a[9] までの値を表示するプログラムを書け。

解答

#include <stdio.h>
main(){
  int a[10]={5,4,2,0,1,9,7,3,8,6};
  int i;
  for(i=0;i<10;i++){
    printf("%d\n",a[i]);
  }
}

演習9-12

整数変数の配列に次のように値が代入されているとする。

int a[10]={5,4,2,0,1,9,7,3,8,6};

この時、画面に a[0] から a[9] までの合計を表示するプログラムを書け。

解答

#include <stdio.h>
main(){
  int a[10]={5,4,2,0,1,9,7,3,8,6};
  int i,sum;
  sum=0;
  for(i=0;i<10;i++){
    sum+=a[i];
  }
  printf("%d\n",sum);
}

演習9-13

浮動小数点変数の配列に次のように値が代入されているとする。

float x[10]={5.0,4.0,2.0,0.0,1.0,9.0,7.0,3.0,8.0,6.0};

この時、画面に x[0] から x[9] までの平均を表示するプログラムを書け。

解答

#include <stdio.h>
main(){
  float x[10]={5.0,4.0,2.0,0.0,1.0,9.0,7.0,3.0,8.0,6.0};
  float sum,average;
  int i
  sum=0.0;
  for(i=0;i<10;i++){
    sum+=x[i];
  }
  average=sum/10.0;
  printf("%f\n",average);
}

演習9-14

文字列が次のように文字型配列変数に与えられているとする。

int k=6;
char a[]="This is a sample string.";

このとき、文字列の k 文字目(つまり 6 文字目)を出力するプログラムを 書け。

解答

#include <stdio.h>
main(){
  int k=6;
  char a[]="This is a sample string.";
  printf("%c\n",a[k+1]);
}

演習9-15

文字列が次のように文字型配列変数に与えられているとする。

char a[]="This is a sample string.";

このとき、この文字列の長さを出力するプログラムを書け。

解答

#include <stdio.h>
main(){
  char a[]="This is a sample string.";
  int i;
  i=0;
  while(a[i]!='\0'){
    i++;
  }
  printf("%d\n",i);
}

演習9-16

文字列が次のように文字型配列変数に与えられているとする。

char a[]="This is a sample string.";

このとき、この文字列を逆向きに出力するプログラムを書け。

解答

#include <stdio.h>
main(){
  char a[]="This is a sample string.";
  int i;
  i=0;
  while(a[i]!='\0'){
    i++;
  }
  while(i>=0){
    printf("%c",a[i]);
    i--;
  }
}

演習9-17

文字列が次のように文字型配列変数に与えられているとする。

char c='i';
char a[]="This is a sample string.";

このとき、この文字列中に変数 c の文字(つまり「i」)がいくつ使われて いるかを出力するプログラムを書け。

解答

#include <stdio.h>
main(){
  char c='i';
  char a[]="This is a sample string.";
  int i,num;
  num=0;
  for(i=0;a[i]!='\0';i++){
    if(a[i]==c){
      num++;
    }
  }
  printf("%d\n",num);
}

演習9-18

文字列が次のように文字型配列変数に与えられているとする。

解答

char c='m';
char a[]="This is a sample string.";

このとき、この文字列中で最初に変数 c の文字(つまり「m」)が使われて いる 文字が何番目かを出力するプログラムを書け。

#include <stdio.h>
main(){
  char c='m';
  char a[]="This is a sample string.";
  int i;
  i=0;
  while(a[i]!=c){
    i++;
  }
  printf("%d\n",i+1);
}

演習9-19

変数が次のように定義されているとする。

char a[]="-123";
int i;

このとき、i に a[] が示す数を代入し、i の値を出力するプログラムを書 け。

解答

#include <stdio.h>
main(){
  char a[]="-123";
  int i;
  int j,hugou;
  i=0;
  hugou=1;
  for(j=0;a[j]!='\0';j++){
    if(a[j]=='0'){
      i=i*10;
    }else if(a[j]=='1'){
      i=i*10+1;
    }else if(a[j]=='2'){
      i=i*10+2;
    }else if(a[j]=='3'){
      i=i*10+3;
    }else if(a[j]=='4'){
      i=i*10+4;
    }else if(a[j]=='5'){
      i=i*10+5;
    }else if(a[j]=='6'){
      i=i*10+6;
    }else if(a[j]=='7'){
      i=i*10+7;
    }else if(a[j]=='8'){
      i=i*10+8;
    }else if(a[j]=='9'){
      i=i*10+9;
    }else if((a[j]=='-')&&(hugou==1)){
      hugou=-1;
    }
  }
  i=i*hugou;
  printf("%d\n",i);
}

演習9-20

変数が次のように定義されているとする。

char a[]="-123.02";
float x;

このとき、x に a[] が示す数を代入し、x の値を出力するプログラムを書 け。

解答

#include <stdio.h>
main(){
  char a[]="-123.02";
  float x;
  float div;
  int j,hugou;
  i=0;
  hugou=1;
  for(j=0;(a[j]!='\0')&&(a[j]!='.');j++){
    if(a[j]=='0'){
      x=x*10;
    }else if(a[j]=='1'){
      x=x*10+1;
    }else if(a[j]=='2'){
      x=x*10+2;
    }else if(a[j]=='3'){
      x=x*10+3;
    }else if(a[j]=='4'){
      x=x*10+4;
    }else if(a[j]=='5'){
      x=x*10+5;
    }else if(a[j]=='6'){
      x=x*10+6;
    }else if(a[j]=='7'){
      x=x*10+7;
    }else if(a[j]=='8'){
      x=x*10+8;
    }else if(a[j]=='9'){
      x=x*10+9;
    }else if((a[j]=='-')&&(hugou==1)){
      hugou=-1;
    }
  }
  if(a[j]=='.'){
    j++;
    div=10.o;
    while(a[j]!='\0'){
      /* the case that a[j]=='0' is omitted */
      if(a[j]=='1'){
        x=x+1/div;
      }else if(a[j]=='2'){
        x=x+2/div;
      }else if(a[j]=='3'){
        x=x+3/div;
      }else if(a[j]=='4'){
        x=x+4/div;
      }else if(a[j]=='5'){
        x=x+5/div;
      }else if(a[j]=='6'){
        x=x+6/div;
      }else if(a[j]=='7'){
        x=x+7/div;
      }else if(a[j]=='8'){
        x=x+8/div;
      }else if(a[j]=='9'){
        x=x+9/div;
      }
      j++;
      div*=10;
    }
  }
  x=x*hugou;
  printf("%f\n",x);
}

9. 第十回

演習10-1

  1. 次のプログラムをコンパイルし実行しなさい。
  2. 上記の記法に書き直し、コンパイルし、実行し、結果が同じになる ことを確かめなさい。
#include <stdio.h>
main()
{
  int i,sum;

  sum=0;
  for(i=0;i<50;i=i+1){
    sum=sum+i;
  }
  printf("%d\n",sum);
}

解答

#include <stdio.h>
main()
{
  int i,sum;

  sum=0;
  for(i=0;i<50;i++){
    sum+=i;
  }
  printf("%d\n",sum);
}

演習10-2

i++と++iは意味が違う。 これを調べるため、プログラムを書いて確かめ てみた。 次の問いに答えなさい。

  1. 下記のプログラムがどのような値になるのか予想しなさい。
  2. 実際にコンパイルし動かし、予想と実行結果を比べなさい。
  3. i++と++iの違いを説明しなさい。
#include <stdio.h>
main()
{
  int i,j;

  i=0;
  j=(i=i+1);
  printf("i=%d, j=%d\n",i,j);
  j=(i+=1);
  printf("i=%d, j=%d\n",i,j);
  j=(i++);
  printf("i=%d, j=%d\n",i,j);
  j=(++i);
  printf("i=%d, j=%d\n",i,j);
}

解答

結果
i=1, j=1
i=2, j=2
i=3, j=2
i=4, j=4
i++ と ++i の違い

C 言語では、式そのものに値がある。 例えば、 i=1+1 という式では、 i の値は 2 になるが、式の値も代入された結果である 2 になる。 つまり、 j=(i=1+1)+2 という式では、まず、カッコの中が計算され、 i に 2 が代入されるが、同時にカッコ内の式の持つ値も 2 になる。従って、この場合、 j には 2+2 の値 4 が代入される。

さて、 i++ と ++i は i を 1 だけ増やす式であり、 i の増え方に関しては変わらない。 しかし、これらの式の値は異なる。 i++ は、式の値は 1 を増やす前の値になるが、 ++i は、式の値は i に 1 を増やした後の値になる。 例えば、(1) j=(++i)+2 と (2)j=(i++)+2 という式を比べてみると、これと等しい式は (1)i=i+1;j=i+2; (2)j=i+2;i=i+1; となる。

演習10-3

  1. 次のブログラムを実行しなさい。
  2. 次のプログラムはなにをするプログラムか?
  3. else if の記法を使ってプログラムを書き換え、実行し、同じ動作にな ることを確かめなさい。
#include <stdio.h>
main()
{
  char a[]="100101";
  int i,x;

  x=0;
  for(i=0;a[i]!='\0';i++){
    if(a[i]=='0'){
      x*=2;
    }else{
      if(a[i]=='1'){
        x=x*2+1;
      }
    }
  }
  printf("%s(2) = %d(10)\n",a,x);
}

解答

プログラムの説明

0,1 からなる文字列を 2 進数として十進数に変換する。

#include <stdio.h>
main()
{
  char a[]="100101";
  int i,x;

  x=0;
  for(i=0;a[i]!='\0';i++){
    if(a[i]=='0'){
      x*=2;
    }else if(a[i]=='1'){
        x=x*2+1;
    }
  }
  printf("%s(2) = %d(10)\n",a,x);
}

演習10-4

#include <stdio.h>
main()
{
  char c;
  while((c=getchar())!=EOF)
  {
    putchar(c);
  }
}

上記のプログラムの名前をex10-1.cとする。

  1. このプログラムをコンパイルし、実行せよ。 実行すると、入力待ち になる。次のような入力を与えるとどのようになるか?
        abc(Enter)
        def(Enter)
        Ctrl-Z(Enter)(Ctrl ボタンを押しながら、Z を押す)
    
  2. a.exe < ex10-1.c

解答

  1. abc
    abc
    def
    def
    
  2. プログラムがそのまま表示される。

演習10-5

#include <stdio.h>
#define BUFSIZE 1000
main()
{
  char c;
  char line[BUFSIZE];
  int i;

  do{ 
    i=0;
    c=getchar();
    while((c!=EOF)&&(c!='\n')){
      if(i<BUFSIZE-1){
        line[i++]=c;
      }
      c=getchar();
    }
    line[i]='\0';

    printf("%s\n",line);
  }while(c!=EOF);
}
  1. 上記のプログラムは、 EOF のみの行を読んでも改行を印刷してしま う。 EOF だけを読み込んだ場合、改行を印刷せずにプログラムが終 了するように改良せよ。
  2. テキストファイルを読み込んで、行に行番号をつけて表示するプロ グラムを書け
  3. テキストファイルの一行目だけを印刷するプログラムを書け
  4. テキストファイルの最初の 3 行を印刷するプログラムを書け

解答

  1. 最後の printf の行を次のように変更する。
    if(c!=EOF){printf("%s\n",line);}
    
  2. 初めの定義の部分に次を付け加える。
    int j=1;
    
    そして上記の改良部分を次のようにする。
    if(c!=EOF){printf("%d: %s\n",j++,line);}
    
  3. do の行と最後の while の行を削除する。
  4. 初めの定義の部分に次を付け加える。
    int k=0;
    
    そして最後の while 文を次のように変える。
      }while((c!=EOF)&&(++k<3));
    

10. 第十一回

演習11-1

  1. ファイルの文字数を数えるプログラムを書け
  2. 作ったプログラムの文字数を数えさせよ

解答

#include <stdio.h>
main(){
  char c;
  int i;
  i=0;
  while((c=getchar())!=EOF){
    i++;
  }
  printf("%d\n",i);
}

演習11-2

  1. ファイルの中に「a」という文字がいくつあるか数えるプログラムを書け
  2. 作ったプログラムに「a」が何文字あるか数えさせよ

解答

#include <stdio.h>
main(){
  char c;
  int i;
  i=0;
  while((c=getchar())!=EOF){
    if(c=='a'){
     i++;
    }
  }
  printf("%d\n",i);
}

演習11-3

  1. ファイルの中の「a」という文字を大文字(つまり「A」)に変えて表示するプログラムを書け
  2. 作ったプログラム中の「a」を大文字に変えて表示せよ

解答

#include <stdio.h>
main(){
  char c;
  int i;
  i=0;
  while((c=getchar())!=EOF){
    if(c=='a'){
      c='A';
    }
    putchar(c); 
  }
}

演習11-4

  1. ファイルの行数を数えるプログラムを書け (ヒント: 行は '\n' で終る)
  2. 作ったプログラムの行数を数えさせよ

解答

#include <stdio.h>
main(){
  char c;
  int i;
  i=1;
  while((c=getchar())!=EOF){
    if(c=='\n'){
      i++;
    }
  }
  printf("%d\n",i);
}

演習11-5

  1. ファイルを一行ずつ空けて表示するプログラムを書け
  2. 作ったプログラムを一行ずつ空けて表示させよ

解答

#include <stdio.h>
main(){
  char c;
  int i;
  i=0;
  while((c=getchar())!=EOF){
    if(c=='\n'){
      putchar('\n');
    }
    putchar(c);
  }
}

演習11-6

  1. 3 行目だけを表示するプログラムを書け
  2. 作ったプログラムの 3 行目を表示せよ (注意: ファイルが 2 行以下だったら、何もせずに終了しなくてはいけない。)

解答

#include <stdio.h>
#define BUFSIZE 1000
main()
{
  char c;
  char line[BUFSIZE];
  int i;
  int j;
  j=1;
  do{ /* do{ 文 } while(条件); に関しては後述 */
    i=0;
    c=getchar();
    while((c!=EOF)&&(c!='\n')){
      if(i<BUFSIZE-1){
        line[i++]=c; /* line[i] に c を入れた後、 i を一つ増やす */
      }
      c=getchar();
    }
    line[i]='\0';  /* 行の最後に文字列の終りの文字を入れる */

    if(j==3){
      printf("%s\n",line);
    }
    j++;
  }while((c!=EOF)||j>3);
}

演習11-7

  1. 「a」を含む行だけを表示するプログラムを書け
  2. 作ったプログラムで、「a」を含む行だけを表示せよ

解答

#include <stdio.h>
#define BUFSIZE 1000
main()
{
  char c;
  char line[BUFSIZE];
  int i;
  int j,find;

  do{ /* do{ 文 } while(条件); に関しては後述 */
    i=0;
    c=getchar();
    while((c!=EOF)&&(c!='\n')){
      if(i<BUFSIZE-1){
        line[i++]=c; /* line[i] に c を入れた後、 i を一つ増やす */
      }
      c=getchar();
    }
    line[i]='\0';  /* 行の最後に文字列の終りの文字を入れる */

    find=0;
    for(j=0;line[j]!='\0';j++){
      if(line[j]=='a'){
        find=1;
	break;
      }
    }
    if(find){
      printf("%s\n",line);
    }
  }while(c!=EOF);
}

演習11-8

  1. 各行の先頭 3 文字だけを表示するプログラムを作りなさい。
  2. 作成したプログラムの各行を 3 文字だけ表示しなさい。 (注意: ある行に 2 文字しかなければ、 2 文字だけを表示する)

解答

#include <stdio.h>
#define BUFSIZE 1000
main()
{
  char c;
  char line[BUFSIZE];
  int i;
  int j;

  do{ /* do{ 文 } while(条件); に関しては後述 */
    i=0;
    c=getchar();
    while((c!=EOF)&&(c!='\n')){
      if(i<BUFSIZE-1){
        line[i++]=c; /* line[i] に c を入れた後、 i を一つ増やす */
      }
      c=getchar();
    }
    line[i]='\0';  /* 行の最後に文字列の終りの文字を入れる */

    for(j=0;(j<3)&&(line[j]!='\0');j++){
      putchar(line[j]);
    }
    putchar('\n');
  }while(c!=EOF);
}

演習11-9

  1. 各行の先頭の空白の数を出力するプログラムを書きなさい。
  2. 作成したプログラムの各行の先頭の空白の数を出力しなさい。

解答

#include <stdio.h>
#define BUFSIZE 1000
main()
{
  char c;
  char line[BUFSIZE];
  int i;
  int j;

  do{ /* do{ 文 } while(条件); に関しては後述 */
    i=0;
    c=getchar();
    while((c!=EOF)&&(c!='\n')){
      if(i<BUFSIZE-1){
        line[i++]=c; /* line[i] に c を入れた後、 i を一つ増やす */
      }
      c=getchar();
    }
    line[i]='\0';  /* 行の最後に文字列の終りの文字を入れる */

    for(j=0;line[j]==' ';j++){
    }
    printf("%d\n",j);
  }while(c!=EOF);
}

演習11-10

MS-DOS コマンドの edit は次のようなクセがある。 カーソルは enter を押しても行の先頭に戻らず、前の行の先頭の空白の数と同じ数だけ空白が挿入される。 従って、WWW からカットバッファを利用して edit に貼り付けを行うと、プログラムには余分な空白が挿入されてしまう。

そこで、挿入された余分な空白を取るプログラムを作りたい。 次の流れに従ったプログラムを作りなさい。

  1. 取り除く空白の数 = 0;
  2. ファイルが終るまで以下を繰り返す
    1. 行を読み込む
    2. 空白を取り除いて行を表示する
    3. 取り除く空白の数 = 読み込んだ行にある先頭の空白の数

解答

#include <stdio.h>
#define BUFSIZE 1000
main()
{
  char c;
  char line[BUFSIZE];
  int i;
  int j;
  int space=0;

  do{ /* do{ 文 } while(条件); に関しては後述 */
    i=0;
    c=getchar();
    while((c!=EOF)&&(c!='\n')){
      if(i<BUFSIZE-1){
        line[i++]=c; /* line[i] に c を入れた後、 i を一つ増やす */
      }
      c=getchar();
    }
    line[i]='\0';  /* 行の最後に文字列の終りの文字を入れる */

    for(j=0;j<space;j++){
      if(line[j]!=' '){
        break;
      }
    }
    while(line[j]!='\0'){
      putchar(line[j++]);
    }
    for(space=0;line[space]==' ';space++){
    }
  }while(c!=EOF);
}

演習11-11

入力した数に 1 を足して表示するプログラムを書きなさい。

解答

#include <stdio.h>
main(){
  int x;
  scanf("%d",x);
  printf("\n%d\n",x+1);
}

演習11-12

二つの数を入力し、合計を出力するプログラムを書きなさい。

解答

#include <stdio.h>
main(){
  int x,y;
  scanf("%d",x);
  scanf("%d",y);
  printf("\n%d\n",x+y);
}

坂本直志 sakamoto@c.dendai.ac.jp