] > Circuit Simulator, Repeat sentence

第 9 回 回路シミュレータ, 繰り返し文

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

9-1. Circuit Maker

電気回路

演習9-1

次の合成抵抗を求めなさい。

ヒント
  1. 部品の選択画面 「Devices→Browse... x」 で部品の一覧を表示する画面にし、 Major Device Class から Resistors を選択します。 Minor Device Class から Resistors を選択します。 Device Symbol から Resistor を選択します。 (以後、この操作を Major Device Class, Minor Device Class, Device Symbol の順に (Resistors, Resistors, Resistor)と書きます)

    「Place」ボタンを押すと、作業領域に画面が切り替わります。 白い画面の中央付近を左クリックすると、抵抗を表す記号 抵抗 が表示されます。

    抵抗の記号を指して右クリックして「Duplicate」を選択して、合計 3 本の抵 抗を配置します。 抵抗記号を右クリックして「Edit Device Data」を選びます。 「Label-Value」という欄が抵抗値を表しますので、ここで抵抗値を指定しま す。

  2. メータ選択図 部品表から (Analog, Instruments, Multimeter) を選び 「Place」ボ タンを押し適当な位置で左クリックします。 すると、メータの種類を聞く画面が出るので、「Ohms」を選択し、「Ok」を押 します。

  3. シミュレーションの都合上、基準となる 0 V の点が必要なので、(Analog, Power, Ground) を配置します。
  4. 完成図 「Options→Arrow/Wire」を選び、部品の端同士を結び、回路を完成させます。 完成図は右のようになります。
  5. 「Simulation」を押して、 「Analog Mode」と表示されていることを確認します。 もし、「Digital Mode」が表示されている時は、この「Digital Mode」を選択 すると「Analog Mode」になります。
  6. 「Simulation → Run」を選ぶと画面に合成抵抗値が表示されます。

演習9-2

右の回路図で1Ωの抵抗を流れる電流の大きさを求めなさい。

ヒント

電池は(Anarog, Power, Battery)。 電流を測定するにはマルチメータで current を指定します。 完成図は右のようになります。


電子回路

演習9-3

右の回路図で、A 点と B 点の電圧を調べ、増幅率を求めなさい。

ヒント
  1. 部品を配置して回路図を作成します。 トランジスタは(Transistors, BJTs, NPN TransB) を選び、下のモデル選択画 面から「2N2222A」を選びます。

    1kHz を入力するには、(Analog, Instruments, Signal Gen) を選びます。 電圧の幅を入力するには、Signal Gen の記号を右クリックし、「Edit Signal Generator」を選びます。そして、「Peak Amplitude」の欄に 100mV を入力します。

  2. 「Simulation → Run」を選び、シミュレーションを開始します。
  3. 電圧を測りたい点を左クリックすると、画面下に観測された値がグラフで 表示されます。 別の点を「Shift」キーを押しながら左クリックすると、グラフが重なって表 示されます。
  4. グラフの右側にカーソルがありますので、それを移動してグラフの値を読みと り、出力電位差を計測します。

演習9-4

右の回路図で、A 点と B 点の電圧を調べ、増幅率を求めなさい。


参考文献

鈴木雅臣「実験研究 トランジスタ回路の誕生」トラ技ORIGINAL No.1. CQ出版 (1989)

ディジタル回路

演習9-5

二進数一桁(つまり 0 か 1)を二つ入力して、足し算を実現するディジタル 回路を作りなさい。 但し、真理値表は次のとおりです。

xyz1z0
0000
0101
1001
1110
ヒント
  1. 半加算器の回路は次のようになります。 (x,y)が (0,1) か (1,0) の時に 1、 (0,0) か (1,1) の時に 0 になる論理演算を EX-OR(Exclusive OR, X-OR, 排他的論理和)と言います。
  2. (Digital Basics, Gates, 2-In AND) と (Digital Basics, Gates, 2-In XOR) を配置します。 出力に (Digital Animated, Displays, Logic Display) を二つ、入力用に (Digital, Power, Logic Switch) を二つ配置します。
  3. 回路を配線します。完成図は右のようになります。
  4. 「Simulation」を押して、 「Digital Mode」と表示されていることを確認します。 もし、「Analog Mode」が表示されている時は、この「Analog Mode」を選択 すると「Digital Mode」になります。
  5. 「Simulation → Run」を選びます。 スイッチを入り切りすると、それに応じてスイッチの値の和に対応するランプ が光ります。

演習9-6

右に示す全加算器を利用して、二進数二桁を二つ入力する足し算回路を作り なさい。 全加算器とは 3 つの一桁の二進数の入力の和を二桁の二進数として出力する ものです。

真理値表は次のとおりです。

xycz1z0
00000
01001
10001
11010
00101
01110
10110
11111
ヒント
  1. 足し算器の概念図 筆算と同じ要領で下の桁から順に足していきます。 その時繰り上がりの処理もします。 つまり、次のような回路を作ることになります。
  2. 最下位桁は半加算器で計算します。 そして、下の桁の繰り上がりと、その桁の二つの数の合わせて三つの数の足し 算を全加算器で行います。
  3. 表示に Logic Display を使う代わりに、 (Digital Animated, Displays, Hex Display) も使えます。

9-2. 繰り返し

while文

C 言語でもっとも基本的な繰り返し文は while 文です。 while 文は次のような構文になっていて、 if 文とよく似ています。

while(条件式){
  繰り返し文
}

条件式が正しい限り繰返し文を実行し続けます。 一方、始めに条件式が成立しなければ繰返し文は一回も実行されません。 条件式が成立すると繰返し文が実行されますが、もし繰返しているうちに条件 式が変わらないと永遠に繰り返しが起きてしまいます。 ここが if 文と違うところです。 if 文では条件文の中身を変化させることに意識をする必要はありません。 しかし、 while 文では条件式を繰り返すたびに調べるので、繰り返している間は常に条件が成立し、繰り返しを終える時に条件が不成立に なるように条件を繰返しの中で変化させなければなりません。

そこで、繰り返しの基本的なテクニックとして、次のような変数を導入します。

  1. 条件式の中に現れる。
  2. 繰返し文の中で値が変更される。

このような変数のことをループ変数と言います。

例えば、 5 回だけある処理を繰り返すことを考えます。 その時、ループ変数の役割は繰り返しの回数を数えることです。つまりループ 変数は 1 回目の処理では 1, 2 回目の処理では 2 と、繰り返されるたびにループ変数が 1 ずつ増え る必要があります。 これには次の式を使います。

ループ変数 = ループ変数 + 1;

このようにするとこの式を実行した回数だけループ変数が増えます。 この式を利用してある処理を 5 回だけ実行するプログラムは次のように書け ます。

ループ変数 = 1;
while(ループ変数 <= 5){
  処理;
  ループ変数 = ループ変数 +1;
}

このプログラムにおいて、まずループ変数に 1 が入れられ、 while 文が実行 されます。 そして、while 文の中で処理を行った後ループ変数を 1 ずつ増やすようにす ることで処理を行う回数をループ変数で数えることができるようになります。 while の条件でループ変数の値が 5 以下かどうかをチェックすれば、ちょう ど 5 回だけ処理を行うことができます。 これを実行すると、次のようになります。

  1. ループ変数 = 1
  2. while 条件成立(○ 1≦5)
  3. 処理
  4. ループ変数 = 1+1 = 2
  5. while 条件成立(○ 2≦5)
  6. 処理
  7. ループ変数 = 2+1 = 3
  8. while 条件成立(○ 3≦5)
  9. 処理
  10. ループ変数 = 3+1 = 4
  11. while 条件成立(○ 4≦5)
  12. 処理
  13. ループ変数 = 4+1 = 5
  14. while 条件成立(○ 5≦5)
  15. 処理
  16. ループ変数 = 5+1 = 6
  17. while 条件不成立(× 6≦5)
  18. 終了

これにより処理が 5 回行われたことがわかると思います。

演習9-7

次のプログラムを走らせなさい。 また、このプログラムを改造して 「●」を 10 個表示するプログラムを作り なさい。

#include <stdio.h>
main(){
  int a;
  a=0;
  while(a<5){
    printf("○");
    a=a+1;
  }
  printf("\n");
}

「a=a+1」という記法は、「次の a は、今の a に 1 を足したもの」という意味 になります。つまりこれは漸化式 ai+1 = ai+1 と同じ役割になります。 始めに「a=0」としておいて、「a=a+1」を繰り返すと、「a=a+1」を繰り返した回数 だけ a が増えていきます。繰り返し回数を i とすると、 a の値は i になります。

演習9-8

下のプログラムを走らせなさい。 また、このプログラムを改造し、ループ変 数の値が以下のようになるようにしなさい。

  1. 1, 3, 5, 7, 9
  2. 10, 9, 8, 7, 6
#include <stdio.h>
main(){
  int b;
  b=2;
  while(b<=10){
    printf("ループ変数 = %d\n",b);
    b=b+2;
  }
}

一方、ループ変数を使用して数列の一般項を書くと、数列を表示するこ とができます。

演習9-9

下のプログラムを走らせなさい。 また、このプログラムを改造して、次を表示するようにしなさい(余裕のある 人は最後のカンマ「,」が出ないようにしなさい)。

  1. 1, 3, 5, 7, 9, ... 19
  2. 10, 9, 8, ... , -10
  3. 1, 2, 4, 8, 16, ... 1024
#include <stdio.h>
main(){
  int i,b;
  i=0;
  while(i<10){
    b=2*(i+1);
    printf("%d, ",b);
    i=i+1;
  }
  printf("\n");
}

演習9-10

以下の三角関数の表を出力するプログラムを完成させなさい。

#include <stdio.h>
#include <math.h>
main(){
  int i;
  float x,y;
  i=0;
  while(i<20){
    x = /* x の値は 0 から 2πの間 をとるようにする。 */
    y = /* sin x の値を入れる */
    printf("x=%f, sin(x)=%f\n",x,y);
    /* i の値を更新する */
  }
}

演習9-11

フィボナッチ数列を(20個)表示するプログラムを書きなさい。 但し、フィボナッチ数列とは次のような数列である。

1, 1, 2, 3, 5, 8, 13, 21, 34, 53, ...
a0 = 1 a1 = 1 ai = ai-1 + ai-2 (i2)

C 言語の独特の記法(1)式の値

C 言語では全ての文や式に値を持ちます。 例えば代入文は代入した数を値に持ちます。 j=0 という代入文の値は 0 です。 従って次のような記法が可能です(代入文は右から処理されます)。

i=j=0

この場合、「j=0」 により j に 0 が代入されますが、「j=0」の式の値は 0 なので、 i にはこの式の値 0 が代入されます。

条件文の式の値は、真であれば 1、偽であれば 0 です。従って、0==0 は 1、 1==0 は 0 の値を持ちます。一方、条件文では、 0 なら偽、0 以外の値なら 真だと判定します。したがって、次の文は同じ意味を持ちます。

if(x!=0){}
if(x){}

演習9-12

次の操作で変数 i,j の値はどうなるか?

  1. i=(j=1)+1;
  2. i=((j=0)==0);
  3. if(i){i=0;}

C 言語の独特の記法(2)代入演算子

プログラミングでは i=i+1 など、もともと変数に入っている値を 「増やす」など変化させる操作が 多いです。そのため、これを i+=1 と書くこともできるようになってます。 これを代入演算子と言います。 また、特に 1 を足したり引いたりすることが多いので、特別に 1 増やすのを ++i、 1 減らすのを --i と書くことができます。 これらのそれぞれの式の値は、計算結果の変数の値になります。 一方で、i++, i-- は変数の値を1 増やしたり減らしたり する際に、式の値は増減させる前の変数の値になります。 また、 2 減らすのは i-=2、 5 倍するには i*=5 と書きます。

演習9-13

次のプログラムを実行し、実際に式の値を調べなさい。

#include <stdio.h>
main(){
  int i,j;
  printf("i=0 で i に 1 を増やす\n");
  i=0;j=(i=i+1);printf("i の値 %d, 式の値 %d\n",i,j);
  i=0;j=(i+=1);printf("i の値 %d, 式の値 %d\n",i,j);
  i=0;j=(++i);printf("i の値 %d, 式の値 %d\n",i,j);
  i=0;j=(i++);printf("i の値 %d, 式の値 %d\n",i,j);
}

i++ は配列変数の処理で使います。詳しくは次回以降に説明します。

演習9-14

次のプログラムで何が出力されるか予想しなさい。 そして、実際に実行して、出力が一致するか確認しなさい。 また、画面に 10, 8, 6, 4, 2 と出力されるように改造しなさい。

#include <stdio.h>
main(){
  int i;
  i=5;
  while(i--){
    printf("%d\n",i);
  }
}

演習9-15

次のプログラムが何を出力するのか予想しなさい。 そして、実際に実行して、出力が一致するか確認しなさい。 また、右のパターンを出力するよう、大幅に改造しなさい。

●
●●
●●●
●●●●
●●●●●
●●●●●●
#include <stdio.h>
main(){
  int i, j;
  i=5;
  while(j=i--){
    while(j--){
      printf("○");
    }
    printf("\n");
  }
}

for 文

他の言語では for 文は特別な動作をすることがありますが、 C 言語では for 文は while 文とほぼ同じです。 文法は次のようになります。

for(一番はじめにだけ実行する文 ; 条件文 ; 繰り返しの最後に実行する文 )
{ 繰り返しの内容}

つまり次の二つのプログラムは同じ意味になります。

  1. for(A;B;C){D;}
  2. A; while(B){D; C;}

実際には次のように使います。

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

これは次のプログラムと同じ意味です。

i=0;
while(i<10){
  printf("%d\n",i);
  ++i;
}

for 文で書くと、ループ変数の処理を一か所にまとめることができるので、繰 り返し回数が一目でわかるなどの利点があります。 逆に for の中にループ変数以外の文を多く入れてしまうと読みづらくなりま す。

演習9-16

次のプログラムの for 文を while 文に直しなさい。 また、n に 6, 14, 23 を入れて出力がどうなるか調べなさい。 なお、型が int 同士の割算の商は切捨てになります。 一方、a%b は a 割る b の余りを意味します。

#include <stdio.h>
main(){
  int n;
  n=11;
  for(;n;n/=2){
    printf("%d",n%2);
  }
  printf("\n");
}
参考

数を表す時、下の桁から表すのを little endian と言い、上の桁 から表すのを big endian と言います。 人間は通常 big endian で数を表現しますが、コンピュータでは処理に便利な 場合もあるので、 little endian が使われることがあります。 Intel 社の Pentium Processor は little endian です。


演習9-17

次のプログラムの while 文を for 文に直しなさい。 また、 n の値を 32 や 60 に変えて出力がどうなるか調べなさい。 余裕がある人は約数の数だけ表示するように改造しなさい。

#include <stdio.h>
main(){
  int n,i;
  n=18;
  printf("%dの約数は",n);
  i=1;
  while(i<=n){
    if(!(n%i)){
      printf(" %d",i);
    }
    i++;
  }
  printf("\n");
}

9-3. 宿題

Mupad と Scilab をダウンロードしておいて下さい。


坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科