当ブログをご覧いただき、ありがとうございます。
ご注意事項:
記載内容には、十分注意しておりますが、勘違い、記憶違い、理解不足、思い込み等が無いとは限りませんので、申し訳ありませんが、 記載内容の正確性は保障致しません(出来ません)。
従いまして、このブログの内容を参考にする事に起因して生じる、または 生じた、いかなる事態にも、当方は何の責任も取れませんので、 参考にされる場合は、自己責任にてお願い致します。
このブログのC言語に関する説明には、PICで電子工作するのに必要な事柄以外(私のレベルで)は出てきません、出てこないことの方が多いと思いますので、ご了承願います。

7セグメントLEDに、1~9、0を順次点灯させるプログラムを書く前に、変数の宣言と配列の宣言。

 今回は、7セグメントLED表示器に、1~9、0を順次点灯させるプログラムを書く予定でしたが、それには、変数の宣言と配列の宣言の説明が必要です。

 変数の事は、”C言語でプログラムを書く。 データを記憶する”で説明しましたが、まだ説明していない部分を説明します。

 

f:id:higonohimajin:20210319165050p:plain

 

まず、31行目ですが、関数の宣言文です、メイン関数以外の関数を使う時は、すべての関数より前で関数の宣言をします。

この場合は、char型の結果を出力するsubという名前で、何もデータを受け取らない関数の宣言。

(関数を書く順序は制限がない、メイン関数は必ずしも最初でなくともよい、関数宣言文の順序と実際の関数の順序はそろえる必要はない)

 

23と24行目は、グローバル変数宣言文です、グローバル変数は、そのプログラムの全体から使えて、汎用レジスタの番地が固定的に使用され、プログラムが終わるまで変わりません。

例;char number = 0; と char abc; が宣言されると、number の汎用レジスタが0x30、abc の汎用レジスタが0x36などと指定されプログラムが終わるまで変わりません、さらに、それぞれに0が代入されます。

 (グローバル変数は、初期値が自動的に0になるので、 = 0 は書かなくてもよい、書いても良く、エラーにはならない、ただし、0以外の初期値を必要とする場合は、char number = 0x10;の様に書く)

 

34行目は、ローカル変数宣言文です、ローカル変数は、その関数の中だけに存在し、汎用レジスタの番地が使用されますが、関数から出ると、使用されていた汎用レジスタは、解放されます、したがって使われていた汎用レジスタは、他の関数で使われてる可能性が高く、もし、同じ番地が指定されても、関数を出た時の値は、保証されません。

例;char count = 0; と宣言されると、count の汎用レジスタが0x32と指定され、関数から出ると、使用されていた汎用レジスタは、解放(他の用途に使える)されます、さらに、0が代入されますが、=0を書かないと count の内容は不定(char型だから0x00~0xFFのどれか)になります。

 (ローカル変数は、初期値が自動的に0にならないので、 どこかで、初期値を代入せねばなりません)

 

40行は。sub関数を呼び出し、戻ってきたら、sub関数から出力される変数abcの内容をnumberという変数に書き込みます、この時、変数abcの内容はsub関数の外側でnumberという変数への書き込みに使いますから、ローカル変数では困るのでグローバル変数を使うのです。

 

45行目から54行目までは、sub関数です、return の後ろに、関数から出力する変数または定数を書きます(1つしか書けません)、関数名の最初が voidの時は、return は、省略できます。

 

47行目は、ローカル変数宣言文です、34行目と全く同じローカル変数宣言ですが、34行目と47行目は、全く関係ありません、変数の名前が同じというだけです、これが成立するのは、ローカル変数が宣言された関数内でだけ有効で、関数を出ると使用されていた汎用レジスタは、解放されるからです、よって、34行目と47行目は関数名は同じでも、使用される汎用レジスタは、同じとは限りません、また、sub関数のような関数はほかの関数から何度も呼び出されることがありますが、その都度、汎用レジスタの番地が指定され、関数から出ると、使用されていた汎用レジスタは、解放されます、したがって、ローカル変数は、宣言された関数から、一回外に出れば変数は消滅し、次の回に新たに変数が作られて(名前は同じですが、前の変数とは関係ない)使用されます。

 

ローカル変数がこの様な変数になっているのは、他の関数内の変数を気にせずにプログラムを組めるようにするためです、だだし、グローバル変数は、どの関数からでも操作出来るので、現在のグローバル変数の状態を知ってプログラムを組まないといけませんので、グローバル変数は必要最小限に使い、なるべくローカル変数を使うようにします。

 

下のプログラムは、配列を説明するためのプログラム例です。

f:id:higonohimajin:20210320093954p:plain

28行目は、ローカル変数宣言です。

 

29行目は、配列の宣言です、char 型のdataという名前の配列で、[ ] 内の10は、配列の要素数、= { }は、初期値の代入を表します。

先頭の charは変数の型で、一般の変数の型と同じです。

dataが配列の名前、一般の変数の名前の付け方と同じです。

[10] は、配列の要素数で、配列に幾つの変数を入れるかを表しています。

初期値を代入しない時は、ここまで書けば良く各要素の初期値は0となります。

初期値の代入が必要な場合は、={0x05,0x07,・・・・・,0x00}の様に書き、要素数より初期値の記載が少ないときは、残りの要素には0が入ります。

注;char data[10] の[ ]内の書き方10は、10進数表記で、char data[0x0A]  の16進数表記で書いても良い、初期化は data[0] が0x05 、 data[1] が0x07  のように書かれた初期値の先頭から順番に格納されます。

 

35行目は、配列のデータをPORTBに代入しています、この時のdataの[ ]内の変数(count)には、0~9までの数値を入れなければなりません、10個の要素を宣言したので、0~9までです、要素の指定番号([ ]内に書く)指定番号は0から数え始めますので、0~9までの10個となります。

 

配列を宣言する場所で、変数と同じように、グローバルな配列かローカルな配列になるかが決まり、変数と同じように振舞います、29行目は、ローカルな配列の宣言です。

配列の初期値の一括代入は、宣言の時しかできません、宣言以外の場所で初期化する場合は、data[3] = 0x05; 、 data[4] = 0x00; のように、一つづつ代入します。