スキップしてメイン コンテンツに移動

投稿

2023の投稿を表示しています

C言語で放物線を描く

初速度を入力して放物線を描くプログラムです。 物体を真上に投げることを鉛直投げ運動といいます。 時間の経過に伴う物体に高さをグラフにすると放物線になります。 プログラムのすべてを解説しています。

最大公約数と最小公倍数を求めるプログラム【C言語】

分数の足し算を学習プログラムを作成しました。 2つの分数の分母を同じ数字に揃える通分の処理に 最大公約数と最小公倍数を求める必要があります。 C言語による最大公約数と最小公倍数の求め方を解説します。

C言語で打ち上げ花火【円周上の座標を求める】

打ち上げ花火のプログラムをC言語で作成しました。 三角関数(sin、cos)で求めた円周上の座標に「*」を表示して花火を表現しています。

C言語でハノイの塔 「再帰」で超簡単攻略

ハノイの塔を解くプログラムをC言語で書きました。 ハノイの塔は左端の円盤をルールに従って中央もしくは右端に移動させるパズルです。 ルールは、常に、小さな円盤の上に大きな円盤が乗らないように移動させることです。

もう曖昧にしない 非安定マルチバイブレータ 完全理解

非安定マルチバイブレータ回路は 左右のトランジスタが交互にON、OFFを繰り返す回路です。 非安定マルチバイブレータ回路は 電子工作において定番の回路ではあります。 ただし、その動作原理は非常に難しく 正確に理解している人はあまりいないのではないでしょうか? もう曖昧にしない。 非安定マルチバイブレータ回路の動作原理の 完全理解を目指しましょう。

AMラジオ受信のしくみ<ゲルマラジオ>

 コイルとコンデンサによるLC共振回路によって 搬送波の周波数を選択します。 次にゲルマニウムダイオードで 搬送波のプラス側だけ取り出します(検波)。 最後にコンデンサで高周波成分(搬送波のプラス側)を取り除いて 信号波のみを取り出します(包絡線検波)。

AMラジオ送信のしくみ

低周波数の音声や音楽などの信号波を 高周波数の搬送波にのせて(変調して)送信しています。 AMラジオの変調方式は、 信号波を搬送波の振幅の変化として変調する方式です。 なお、NHK第1の594Hz(東京、埼玉など)など、 局番の周波数は搬送波の周波数です。

LEDをゆっくり点灯

 Vin=9V、コレクタ電流=20mA、ベース電流=0.125mAの回路で、Vbb(駆動電源)を5Vと決めると、R2=32kΩ((9V-5V)/0.125mA)、R3=34kΩ((5V-0.7V)/0.125mA)になります。 C1=100uFにすると、時定数τ=3.2s(32kΩ*100uF)になるので、LEDは数秒かけてゆっくり点灯します。  「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

抵抗の分圧回路

 Vout = Vin * R2 / (R1 + R2) (例)Vin = 9V、R2 = 100kΩ、Vout = 5VにおけるR1の抵抗値を求めなさい。 IR2 = 5V / 100kΩ = 0.05mAなので、IR1 = IR2 = 0.05mAです。 R1の電位差は、9V - 5V = 4Vだから、R1の抵抗値は、R1 = 4V / 0.05mA = 80kΩになります。 「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

微分回路

 Vinが5Vになった瞬間はC1は短絡の状態になるのでVout=Vin=5Vです。 C1が充電されて5VになるとVout=Vin-5=0Vです。 Vinを0Vに変化させ瞬間はC1は充電された状態なのでVout=Vin-5=-5Vです。 C1が放電されて0VになるとVout=Vin-0=0Vです。 「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

トランジスタのスイッチ回路

 (例)コレクタ電流を20mA(飽和領域)で動作 トランジスタのhFEが160程度、入力信号が5Vだとすると、ベース電流は0.125mA(20mA÷160)、ベース抵抗は33kΩ((5V-0.7V)÷0.125mA)です。 リーク電流を10μA以下と仮定すると、ベースエミッタ間抵抗は68Ω(0.7/10μA)です。 「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

ベースエミッタ間抵抗

 ノイズやリーク電流がベース側に流れ込むことを防止することができます。 これらの極小電流はベースエミッタ間抵抗を経由して、すべてエミッタ側に流れます。 予期せぬコレクタ電流の変動を防ぐことができます。   「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

ベースエミッタ間電圧

 ベース電流が少しでも流れると、ベースエミッタ間には電位差が生じます。 ベース電流が大きくなると、ベースエミッタ間電圧は高くなります。 ベースエミッタ間は、ダイオードと同じ構造なので、ベースエミッタ間電圧の最高値は、ダイオードの順方向電圧(0.7V程度)と同じです。 「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

トランジスタの飽和領域

 ベース電流の大きさによってコレクタ電流が変動します。 コレクタ電流はベース電流に電流増幅率(hFE)をかけた大きさになります。 ベース電流をある程度大きくすると、コレクタ電流はこれ以上増加しない飽和領域になります。 この時、コレクタエミッタ間電圧≒0Vになります。 「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

LEDの点灯

 日亜の白色LED(NSPW500BS、VF:3.6V、VI:20mA)を点灯させる回路です。 電源電圧を9Vにすると、LEDと抵抗には、それぞれ3.6V、5.4V(9V-3.6V)の電圧がかかります。 このとき、LEDに流れる電流は20mAなので、抵抗値は5.4V/20mA=270Ωになります。 シミュレーションともほぼ一致しています。  「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

RC回路の時定数τ(タウ)

 時定数τは、Voutが平衡状態(Vout=Vin)の63.2%になるまでの時間です。 平衡状態に移るまでの過渡現象がどのくらい続くのかを表す目安になります。 (式)時定数τ = CR [s] (例)R=10kΩ、C=47μFのとき 時定数τ = CR = 10*10^3*47*10^-6 = 0.47 [s]  「発見による学習(Learning by Discovery)」というプロセスを通じて学ぶ、新しい世代のためのエレクトロニクス入門書です。図はすべてフルカラーでとてもわかりやすいです。

真理値表から加法標準形の論理式を求める方法

 出力Fが1の入力について、0なら論理否定、1なら論理肯定の単純積を作って、その論理和をとります。 求めた加法標準形の論理式をベイチ図を使って簡単化します。 F = ¬A・¬B・C + A・¬B・¬C + A・B・¬C   ↓ F = A・¬C + ¬A・¬B・C

論理式の簡単化

 ベイチ図を使って加法標準形の論理式を単純化します。 (例)F = ¬A・¬B + A・¬Bを単純化します。 ベイチ図より F = ¬B と単純化できます。

3変数のベイチ図

 3個の変数を含む論理式の場合は3変数のベイチ図を利用します。 

ベイチ図

 ベイチ図を使うとベン図と同じように論理式を視覚的に表現することができます。 加法標準形の論理式を単純化する際にベイチ図を利用します。 

加法標準形の論理式

 F = [単純積] + [単純積] + ・・・ + [単純積] A・Bのような単純積が論理和の形で表されている論理式です。 (例)F = ¬A・¬B + ¬B・(A + B)を加法標準形に変形する。 分配の法則より F = ¬A・¬B + A・¬B + B・¬B 補元の法則より F = ¬A・¬B + A・¬B

電子工作で使うブール代数

 (結合の法則) ① A ∪ (B ∪ C) = (A ∪ B) ∪ C ② A ∩ (B ∩ C) = (A ∩ B) ∩ C (分配の法則) ① A ∩ (B ∪ C) = (A ∩ B) ∪ (A ∩ C) ② A ∪ (B ∩ C) = (A ∪ B) ∩ (A ∪ C) (ド・モルガンの法則) ① ¬(A ∪ B) = ¬A ∩ ¬B ② ¬(A ∩ B) = ¬A ∪ ¬B

電子工作で使うブール代数

 ブール代数はベン図を使て考えると覚えやすいです。 (吸収の法則) ① A ∪ A ∩ B = A ② A ∩ ( A + B ) = A

電子工作で使うブール代数

 ブール代数はベン図を使って考えると覚えやすいです。 (補元の法則) ① A ∪ ¬A = 1 ② A ∩ ¬A = 0

電子工作で使うブール代数

 ブール代数はベン図を使って考えると覚えやすいです。 (恒等の法則) ① 1 ∪ A = 1 ② 0 ∪ A = A ③ 1 ∩ A = A ④ 0 ∩ A = 0

抵抗の定格電力

 例えば、430Ωの抵抗に20mAの電流が流れるときの消費電力は以下の式で求まります。 消費電力[W]  = 電圧[V] * 電流[A] = 抵抗[R] * 電流[A] * 電流[A]   = 430 * 0.02^2 = 0.172[W] よって、定格電力が1/4W(0.250W)以上の抵抗を選択します。

電子工作でよく使う接頭語

 10の累乗倍を表す記号が接頭語です。 接頭語を使って数値を扱いやすくします。 ミリ[m] 10^-3 マイクロ[μ] 10^-6 ナノ[n] 10^-9 ピコ[p] 10^-12 (例)単位変換 10*10^4[pF] =10*10^4*10^-12[F] =10*10^4*10^-6*10^-6[F] =10^-1*10^-6[F] =0.1[μF]

exit(0)とreturn 0の違い

 hoge1関数内のexit(0)は、その場でプログラムを強制終了します。 hoge2関数内のreturn 0は、呼び出し元のmain関数に戻ります。

gets関数が廃止された理由

バッファオーバーフローの脆弱性があるため廃止されました。 fgets関数がgets関数の代替として利用できます。 ただし相違点はあります。 fgets関数は入力の改行文字がバッファに格納されます。 また入力ストリーム上にバッファが残ってしまう仕様です。

ポインタの戻り値

関数内のstaticなしで定義した変数は関数が終了すると解放されます。 自動変数領域のアドレスを関数の戻り値にすることはできません。 静的領域に割り付けられる文字列リテラルのアドレスは戻り値にすることができます。

関数内のstatic

関数内でstaticをデータ型の前に追加して変数を初期化すると、 その変数に対してプログラム終了時まで有効な静的領域が確保されます。 初期化は一度のみで、 関数が複数回呼び出された場合は、 前回に呼び出されたときの値が保持されています。

const

constをデータ型の前に追加して初期化すると 変数の値、配列の要素、ポインタが指し示す先の値が変更不可になります。 const int a = 5; const int b[] = {10,20}; const char s[] = "papa"; const char *p = "kingyo"; 以下はpの値が変更不可になります。 char * const p = "kingyo";

fopne()とopen()の違い

fopne()は高水準入出力、 opne()は低水準入出力としてファイルをオープンします。 高水準入出力はHDDなどの外部補助記憶装置へのアクセス回数を減らすためにメインメモリのバッファ領域を介してファイルの入出力を行います。 低水準入出力はバッファリングを行いません。

変数とアドレス

&aは5の格納先アドレスです。 &b[0]は10、&b[1]は20の格納先アドレスです。 bと&b[0]は等価です。 &s[0]は'p'、&s[1]は'a'の格納先アドレスです。 sと&s[0]は等価です。 &dt.noは100の格納先アドレスです。 &dtと&dt.noは等価です。

安全なポインタの使い方

 ①変数宣言時にNULL(0番地)で初期化します。 int a = 5; int *p1 = NULL; p1 = &a; ②指し示す先を参照する前にNULLチェックします。 if(p1 != NULL){printf("%d\n",*p1)}; ③指し示す先のメモリを解放したらNULLを代入します。 free(p2); p2 = NULL;

ダブルポインタ

ダブルポインタはポインタのポインタです。変数の前に「**」をつけて宣言します。 int a = 5, *p, **PP; p = &a; pp = &p; *p:pが指し示す先の値(aの値) *pp:ppが指し示す先の値(pの値) **pp:ppが指し示す先が指し示す先の値(aの値)

文字列をポインタで管理

 char *p1 = "Hello"; p1に文字列の先頭アドレスが格納されます。 printf("%s\n",p1); static char *p2[] = {"Papa","Kingyo"}; p2[0]、p2[1]に各文字列の先頭アドレスが格納されます。 printf("%s\n",p2[0]); printf("%s\n",p2[1]);

文字列を配列として格納

 static char str1[] = "Papa"; 配列名は文字列が格納されている先頭アドレスです。 printf("%s\n",str1); static char str2[][10] = {"Papa","Kingyo"}; 配列名[添字]は各文字列が格納されている先頭アドレスです。 printf("%s\n",str2[0]); printf("%s\n",str2[1]);

ポインタを理解する

初期化した変数aとポインタ変数pを宣言します。 int a = 5, *p; pにaのアドレスを格納します。 このとき、pはaを指し示すといいます。 p = &a; *pでpが指し示す先の値を参照できます。 pが指し示す先はaです。 printf("*pの値 = %d\n",*p);

加算による減算

 引く数の補数を用いると減算を加算で表現できます。 例えば「15-8=7」について、 引く数「8」の補数「2」を用いて、加算で表現すると「15+2=17」となります。 結果「17」の最上位の桁を取り除くと「7」となり、 減算の結果と同じになります。 2進数の減算 例えば「6-2=4」を4ビットの2進数で加算表現します。 「6」は「0110」、「2」は「0010」で、 その補数は「1110」だから「0110」+「1110」=「10100」となります。 5ビットの「1」は、桁あふれなので無視すると、 結果は「0100」となります。 「0100」は10進数の「4」です。

2進数の正負の数

 2進数の正⇔負の変換は、先頭に「+」「-」を付けるのではなく、2の補数で行います。 例えば、10進数の「3」は、4ビットの2進数で「0011」ですが、 「0011」の2の補数「1101」が、10進数の「-3」であり、 「1101」の2の補数「0011」が、10進数の「3」です。 符号付き2進数において最上位ビットは符号を表す符号ビットとして使用されます。 符号ビットが「0」だと正の数、「1」だと負の数になります。 <4ビットの2進数> 0000 0 0001 1 1111 -1 0010 2 1110 -2 0011 3 1101 -3 0100 4 1100 -4 0101 5 1011 -5 0110 6 1010 -6 0111 7 1001 -7             1000 -8

補数

ある数に対して、桁上がりさせることができる最小の数を補数といいます。 例えば、8の補数は2、85の補数は25です。 特に、10進数における補数を10の補数といいます。 10進数において、桁上がりさせない最大の数を「9の補数」といいます。 例えば、8の「9の補数」は1、85の「9の補数」は24です。 2進数における補数 例えば「0110」の補数は「1010」です。 「0110」に「1010」を足すと「10000」となって桁上がりさせます。 特に、2進数における補数を2の補数といいます。 2進数において、桁上がりさせない最大の数を「1の補数」といいます。 例えば「0110」の「1の補数」は「1001」です。 「0110」に「1001」を足すと「1111」となって桁上がりしない最大の数になります。 ビット反転させると「1の補数」になります。 「1の補数」に1を足すと「2の補数」になります。

ファイルディスクリプタ(fd)

 ファイルを識別するための整数値です。 stdin、stdio、stderrのfdはそれぞれ0、1、2になります。 ファイルオープンするとfdは3から順番に割り当てられます。 open()でオープンに成功するとfdを返す。 fopen()ではFILE構造体のメンバ「_fileno」でfdを確認できます。

乱数の生成

 void srand(unsigned int seed) time()で取得したtime_t型の整数値を符号なし整数型にキャストして乱数系列を初期化するseed値とします。 int rand( void ) 乱数は0からRAND_MAXの範囲内の擬似乱数を返します。

ヘッダファイルの格納場所

 gccでオプション-vを使ってコンパイルすればヘッダーファイルの格納場所を確認できます。 #include <...> search starts here:  /usr/lib/gcc/x86_64-linux-gnu/9/include  /usr/local/include  /usr/include/x86_64-linux-gnu  /usr/include End of search list.

2038年問題

 C言語で書かれてるシステムにおいて「time_t型」を32ビットの符号付き整数の範囲で扱っている場合は、1970年1月1日0時0分0秒から2147483647秒を経過した、2038年1月19日3時14分7秒を過ぎると、値がオーバーフローして、時刻を正確に扱えず、システムが誤作動する問題です。

time_t型

 1970年1月1日午前0時0分0秒からの経過秒数を扱うデータ型です。 値は32ビットまたは64ビットの符号付き整数の範囲です。 (32ビットの符号付き整数) -2147483648 ~ 2147483647 (64ビットの符号付き整数) -9223372036854775808 ~ 9223372036854775807

エスケープシーケンスによる画面制御

 ESCコードと [(角括弧)と制御文字列によって、文字に色をつけたり、カーソル位置を指定したりできます。

ヘッダファイルと標準ライブラリ

 printf( ) 関数のプロトタイプはヘッダファイル stdio.h に記述されています。 関数の定義(処理内容)は事前にコンパイルされた状態で標準ライブラリ libcに収録されています。 標準ライブラリ はコンパイル時に-lcを指定しなくても自動的にリンクされます。

関数のプロトタイプ宣言

 main()関数内で他の関数を呼び出す場合は、呼び出される関数の処理を事前に記述しておく必要があります。 ただし、以下のプロトタイプ宣言さえすれば、関数の処理は任意に場所に記述することができます。 <プロトタイプ宣言> 戻り値の型 関数名(引数の型,・・・);

コマンドライン引数

 int main(int argc, char *argv[])の引数のことです。 argcには引数の数、配列argvには引数の文字列が格納されます。

非安定(無安定)マルチバイブレータ回路

非安定(無安定)マルチバイブレータ回路は、左右のトランジスタが交互にON、OFFを繰り返す回路です。 電子工作において、定番の回路ですが、その動作原理は非常に難しく、正確に理解している人はあまりいないのではないでしょうか。 いっしょに、非安定(無安定)マルチバイブレータ回路の動作原理の完全理解を目指しましょう。 ①トランジスタQ1にベース電流が流れて、トランジスタQ1がON状態になったと仮定します。左側のLEDは点灯します。eB2は約0.6Vの電位になりますので、ベース電流は約0.12mA((6V-0.6V)÷47kΩ)です。 ②この回路のベース電流は約0.12mAだから、コレクタ電流は約12mA(0.12mA×100)となるので、トランジスタQ1がON状態では、e1は約0Vの電位になります。 ※トランジスタを飽和領域で利用する場合は、コレクタ・エミッタ間電圧は約0Vになります。この回路の飽和領域は、コレクタ電流が約12mA((6V-2V)÷330Ω)流れるときです。 ③コンデンサC1の極板間には電位差があるので、e1が0Vになれば、eB1はコンデンサC1の極板間の電位差分だけマイナスの電位になります。 ④eB1の電位がマイナスになると、トランジスタQ2にベース電流が流れなくなるので、トランジスタQ2がOFF状態になります。 右側のLEDは消灯します。 このときe2の電位は約6Vです。 ⑤コンデンサC1の放充電によりeB1の電圧は次第に上昇して、 トランジスタQ2にベース電流が流れ始めます。 このとき、eB1は約0.6Vの電位になります。 ⑥トランジスタQ2にベース電流が約0.12mAが流れて、トランジスタQ2がON状態になります。右側のLEDは点灯します。e2は約0Vの電位になります。 ⑦コンデンサC2の極板間には電位差があるので、e2が0Vになれば、eB2はコンデンサC2の極板間の電位差分だけマイナスの電位になります。 ⑧eB2の電位がマイナスになると、トランジスタQ1にベース電流が流れなくなるので、トランジスタQ1がOFF状態になります。 左側のLEDは消灯します。このときe1の電位は約6Vです。 ⑨コンデンサC2の放充電によりeB2の電圧は次第に上昇して、トランジスタQ1にベース電流が流れ始めます。このとき、eB2は約0.6Vの電位になります。 ⑩トランジス