ページへ戻る

− Links

 印刷 

FDIII-HC Starter Kit Guide​/Chapter1.4 のソース :: Besttechnology

knowledge:FDIII-HC Starter Kit Guide/Chapter1.4のソース

« Prev[3]  
*C言語の基礎 [#pcd8150f]
このページでは[[FREEDOM IIIライブラリ>FDIIILIB]]を使用した場合のC言語について説明をします。~

**基本 [#f828bd2e]
***2進数・16進数 [#i00e054a]
日常的に使用されている10倍毎に位を取る(桁上がりする)表記方法は10進法と呼ばれており、馴染み深いものとなっていますが、コンピュータの世界では2進法や16進法での表記が行われることがあります。~
1桁で表記できる数字はそれぞれの基数-1です。2進数であれば0と1しか表記できず、10進数であれば0から9までが、16進数では0から15までが表記可能となります。但し、10以上は数字として1桁表記することができないため、英字を使用します。~
下表は10進数と2進数、及び16進数の対応表です。
| 10進数 | 2進数 | 16進数 |
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 10 | 2 |
| 3 | 11 | 3 |
| 4 | 100 | 4 |
| 5 | 101 | 5 |
| 6 | 110 | 6 |
| 7 | 111 | 7 |
| 8 | 1000 | 8 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 11 | 1011 | B |
| 12 | 1100 | C |
| 13 | 1101 | D |
| 14 | 1110 | E |
| 15 | 1111 | F |
| 16 | 10000 | 10 |

***ビット・バイト [#z62e3ad6]
コンピュータの世界で使われる情報(データ)の最小単位をビットと言います。1ビットは0か1の値を扱い、2進数の1桁分が扱う大きさとなります。~
~
また1ビットが8個集まったものを1バイト(=8ビット)と言います。~
#ref(bitbyte.png,100%)
1バイトで表すことができる数値は10進数で表すと0~255です。

下表は10進数を2進数で表した例です。
| 10進数 | 2進数 |
| 0 | 00000000 |
| 50 | 00110010 |
| 128 | 01000000 |
| 200 | 11001000 |
| 255 | 11111111 |

***変数 [#h0d4cb7f]
変数は数値や文字を置いておく入れ物です。~
変数を使い始める前に「このようなデータを入れるこんな名前の入れ物を使います」と宣言しなければなりません。
#ref(variable1.png,100%)
「int型のデータを入れるaという名前の入れ物を使います」と宣言しています。
int型というのは4バイトの整数という意味です。詳しくは後述します。~

#ref(variable2.png,100%)
 a=24;
は変数aに24という整数を入れることになります。
***データ型 [#p7400a94]
変数は使い始める前に「このようなデータを入れるこんな名前の入れ物を使います」と予め宣言しておかなければなりません。「このようなデータ」を型と言います。~
FDIII-HCを使用する際のデータ型には以下のように、それぞれサイズと入る値の範囲が異なります。

| 型の名前 | サイズ  | 入る値の範囲 | 備考 |
| int8_t   | 8ビット |    -128~127 | 8ビット指定 |
| char     | 8ビット |    -128~127 | |
| uint8_t  | 8ビット | 0~255 | (8)ビット指定 |
| unsigned char | 8ビット | 0~255 | |
| int16_t  | 16ビット | -32768~32767 | 16ビット指定 |
| short    | 16ビット | -32768~32767 | short int |
| uint16_t | 16ビット | 0~65535 | 16ビット指定 |
| unsigned short | 16ビット | 0~65535 | |
| int32_t  | 32ビット | -2147483648~2147483647 | 32ビット指定 |
| long     | 32ビット | -2147483648~2147483647 | long int |
| int      | 32ビット | -2147483648~2147483647 | |
| uint32_t | 32ビット | 0~4294967295 | 32ビット指定 |
| unsigned long | 32ビット | 0~4294967295 | |
| unsigned int  | 32ビット | 0~4294967295 | |

変数は数値や文字を置いておく入れ物でした。
大きい入れ物なら大きな数字も入れられるので、変数のサイズが大きい型を選べば良いと思うかもしれません。
しかしコンピュータが大きいサイズの変数を扱うには、小さいサイズの変数に比べて記憶しておく場所も大きくなり、それに伴う様々な処理にかかる時間も必要になってきます。

***演算子 [#k3be0d0f]
基本的な演算子には以下があります。
| 演算子 | 意味 | 使用例 |
| = | 右辺を左辺に代入 | a = b |
| + | 足し算 | c = a + b |
| - | 引き算 | c = a - b |
| * | 掛け算 | c = a * b |
| / | 割り算 | c = a / b |
| % | 割り算の余り | c = a % b |

算数でa=bは、aとbは同じという意味で使うのが一般的ですが、C言語では右辺を左辺に代入します。例えばa=2を左辺、b=3を右辺とし、a=bにすると、bの値がaに代入されa、b両方とも3になります。このため、代入演算子と呼ばれています。~
四則演算に加え、余りを出す演算子を合わせて算術演算子と呼びます。

その他に以下の演算子があります。
基本的な演算子で書き換えることもできますが、プログラムを見易く、短くするために使います。
| 演算子 | 使用例 | 基本演算子で表すと |
| += | a += b | a = a + b |
| -= | a -= b | a = a - b |
| *= | a *= b | a = a * b |
| /= | a /= b | a = a / b |
| %= | a %= b | a = a % b |
| ++ | a++ | a = a + 1 |
| -- | a-- | a = a - 1 |
- 補足
a++と++aの違いについて~
 a++;
と単一行で使用する場合は、
 ++a;
と同じ意味になりますが、単一行以外の使用では加算するタイミングが異なります。~
#html{{
<pre class="brush: c">
void main (void) {
  int i = 0;
  while (i++ < 10);
}
</pre>
}}
上記の場合、iは0 1 2 3 4 5 6 7 8 9 10と遷移し0~9の10回の繰り返しが行われます。
#html{{
<pre class="brush: c">
void main (void) {
  int i = 0;
  while (++i < 10);
}
</pre>
}}
上記の場合は、iは1 2 3 4 5 6 7 8 9 10と遷移します。そのため、1~9の9回しか繰り返しは行われません。~
これは++の位置により、1を加えるタイミングが異なるからです。~
~i++ではiを参照(ここではwhileの条件判断)後、1を加えます。
~++iは1を加えた後、iを参照します。
~このルールは--を使用する際も適用されます。但し、--の場合は加算ではなく、減算となります。

***比較演算子 [#db59b61c]
比較演算子は後で説明する制御文の条件になります。

| 比較演算子 | 使用例 | 意味 |
| == | a == b | aとbは等しい |
| &#x3c; | a < b | aはbより小さい |
| &#x3e; | a > b | aはbより大きい |
| <= | a <= b | aはb以下 |
| >= | a >= b | aはb以上 |
| != | a != b | aとbは等しくない |

例えば「もしa<bだったら、aに1足す」という制御文を書いた場合、a=3,b=4ならa<bが成り立ちaに1が足されますが、a=4,b=4ならa<bが成り立たないので何もされません。

***論理演算子 [#seea64bd]
論理演算子は後で説明する制御文の条件を組み合わせる時に使用します。

| 論理演算子 | 使用例 | 意味 |
| && | 3 <= a &&  a<= 8 | aは3以上かつ8以下 |
| ! | !(a == 5) | aは5ではない |
| &#x7c;&#x7c; | a < 3 &#x7c;&#x7c; 8 < a | aは3未満または8より大きい |

***アドレス [#s0d770ec]
アドレスとは変数がコンピュータのメモリのどこにあるかを指します。
その名の通りコンピュータ上の住所のようなものです。~
 &a
と書くと変数aのアドレスとなります。この&をアドレス演算子と呼びます。~
主に変数としてaが宣言されている場合に使用します。~
#html{{
<pre class="brush: c">
  int a, b = 3;
  a = &b;
</pre>
}}
aには3ではなく、bのアドレスの値が入ります。~

***配列とポインタ [#de8fd791]
アドレスを利用するには配列とポインタをしっかりと学ぶ必要があります。~
****配列とは [#ze3b2962]
配列はその変数の型の配列数分メモリ領域を確保します。確保された配列上は型さえ一致すれば何を代入しても問題ありません。~
宣言方法は以下の通りです。
#html{{
<pre class="brush:c">
  char a[5] = "BEST";
</pre>
}}
#ref(table.png,100%)

****ポインタとは [#o91e72b0]
ポインタは実体をもちません。ポインタはメモリ上のどこかに確保されたデータのアドレスのみを受け渡します。
宣言方法は以下の通りです。
#html{{
<pre class="brush:c">
  char *a = "BEST";
</pre>
}}
#ref(pointer.png,100%)
使用方法は配列とあまり変わりませんが、BESTという文字列を操作するにはアドレスを介して操作するしかありませんので、*を間接演算子と呼びます。~
間接演算子の簡単な使い方を紹介します。
#html{{
<pre class="brush:c">
#include &lt;fd.h&gt;
void main (void) {
  char *a = "BEST", *b;
  int i = 0;
  b = a;
  while (*b++) i++;
  fd_printf ("%s is %d byte\n", a, i);
}
</pre>
}}
 b = a;
ポインタaが示すアドレスをポインタbへ代入します。(この時点でa/bは同じアドレスを指し示します)~
 while (*b++) i++;
これは以下の命令を簡素化したものです。
 while (1) {
   if (*b == NULL) break;
   b++;
   i++;
 }

以下にアドレス演算子、配列を使用した場合と比較してみます。
| 状態 | アドレス演算子 | 間接演算子 | 配列 |
| 宣言 | char a; | char *a; | char a[3]; |
| アドレスを渡す | b = &a; | b = a; | b = &a[0]; |
| 内容を渡す | b = a; | b = *a; | b = a[0]; |
文字列の場合は配列と同じ扱いとなります。
"BEST"は、文字としては4文字ですが、メモリ上は5バイト確保されます。C言語では"BEST"は只の文字データが4つ集まっているだけであり、文字列としては扱われません。"BEST"の最後にNULLが付与されて初めて文字列として扱われます。~
つまり~
 char *a = "BEST";
は~
 char a[5] = { 'B', 'E', 'S', 'T', NULL };
と同じことです。~
このため、配列として扱うことで、文字の取得が可能となっています。以下はbに'E'を代入します。~

#html{{
<pre class="brush: c">
 char *a = "BEST", b;
 b = a[1]; // 2文字目を代入します
</pre>
}}
ポインタを使用して文字の取得を行う場合は以下の通りです。~
#html{{
<pre class="brush: c">
 char *a = "BEST", b, *c;
 c = a;  // アドレスをコピーします
 c++;    // アドレスを1つ進めます
 b = *c; // アドレスの示す内容(E)を代入します
</pre>
}}

**制御文 [#j38a6a23]
***if文 [#c6144380]
if文は「もし○○だったら△△する。それ以外だったら□□する」というような、条件によって実行を分岐する時に使います。
#ref(if1.png,100%)
「もし○○だったら△△する」というif文です。~

()内の条件が成り立っている時は{}内の処理を実行します。成り立っていない時は実行しません。
#html{{
<pre class="brush: c">
 main() {
   int a =10;
   if (a > 5) {
     a = a - 1;
   }
 }
</pre>
}}
もし変数aが5より大きかったらaから1を引くというプログラムです。aは10なのでa>5が成り立っており、aから1が引かれます。
----
#ref(if2.png,100%)
「もし○○だったら△△する。それ以外だったら□□する」というif文です。~

()内の条件が成り立っている時はその直後の{}内の処理を実行し、成り立っていない時はelse後の{}内の処理を実行します。
#html{{
<pre class="brush: c">
 main() {
   int a =3;
   if (a > 5) {
     a = a - 1;
   }
   else {
     a = a + 1;
   }
 }
</pre>
}}
もし変数aが5より大きかったらaから1を引いて、それ以外(aが5以下)なら1を足すというプログラムです。aは3なのでa>5は成り立たずelse内のaに1を足すが実行されます。
----
#ref(if3.png,100%)
「もし○○だったら△△する、それ以外でもし●●だったら□□する、更にそれ以外は■■する」というif文です。~

最初のifの()内の条件が成り立っている時はその直後の{}内の処理を実行し、成り立っていない時は次のelse ifへ行きます。else ifの()内の条件が成り立っている時はその直後の{}内の処理を実行し、成り立っていない時はelse後の{}内の処理を実行します。~
else ifは複数書くことができます。
#html{{
<pre class="brush: c">
 main() {
   int a = -3;
   if (a > 5) {
     a = a - 1;
   }
   else if (a < 0) {
     a = 0;
   }
   else {
     a = a + 1;
   }
 }
</pre>
}}
もし変数aが5より大きかったらaから1を引いて、それ以外(aが5以下)でかつaが0より小さかったらaに0を代入して、更にそれ以外(aは0以上,5以下)なら a に1を足すというプログラムです。~
aは-3なのでa>5は成り立たず、else ifのa<0が成り立ち、aは0になります。
***for文 [#jea34346]
同じ処理を繰り返す時に使います。通常はカウンタ(何回繰り返したかをカウントする変数)を使って繰り返す回数を決めます。
#ref(for1.png,100%)
「iの初期値を0とし、iが5より小さい間は処理を繰り返す。ただし処理を1回行ったらiを1増やす。」というfor文です。~

事前にカウンタを変数として宣言しておきます。
処理を行うごとにカウンタが0,1,2,3,4と増え5になったら繰返しを止めます。つまり5回同じ処理を繰り返します。~
i++はi=i+1と同じ意味です。
#html{{
<pre class="brush: c">
 main() {
   int i, a = 1;
   for (i = 0; i < 5; i++) {
     a = a * 3;
   }
 }
</pre>
}}
a×3を5回繰り返す(3の5乗を計算する)プログラムです。

***while文 [#o8733fa9]
同じ処理を繰り返す時に使います。for文との違いは、繰り返す回数が定かではない時に使うということです。
#ref(while1.png,100%)
() 内の条件が成り立っている間は処理を繰り返し実行し、条件が成り立たなくなったら繰返しを止めます。
#html{{
<pre class="brush: c">
 main() {
   int i = 1;
   while (i < 1000) {
     i = i * 2;
   }
 }
</pre>
}}
i×2をiに代入する処理を繰り返し、iが1000より少ない状態でなくなったら(1000以上になったら)繰り返しを止めるというプログラムです。
***switch文 [#p5f7a116]
変数や式の値によって処理を分けるときに使用します。
#ref(switch1.png,100%)
「変数・式が値1なら処理Aを実行、値2なら処理Bを実行、どれにも当てはまらなければ処理Cを実行する」というswitch文です。~

switch文の () 内の変数又は式の値がcaseの値と同じならその直後の処理を行います。~
処理後はbreak;を書きます。忘れるとそのまま次の処理も行ってしまいます。~
defaultはどれにも当てはまらない場合です。
#html{{
<pre class="brush: c">
 main() {
   char c = '+';
   int a, m = 5, n = 3;
   switch(c) {
     case '+':
       a = m + n;
       break;
     case '-':
       a = m - n;
        break;
     default:
       a = 0;
   }
 }
</pre>
}}
cが+ならmとnをたしてaに代入、cが-ならmからnを引いてaに代入、それ以外ならaに0を代入するというプログラムです。~
cは+なのでaはm+nになります。~
**関数 [#p52f0f17]
関数とは、パラメータを入れると何かしらの処理を行って結果を吐き出す箱です。~
***FREEDOMライブラリの関数 [#i0705fce]
FREEDOMライブラリの関数は予め箱が用意されているので、箱の中身を気にせずに使う事ができます。~

#ref(function1.png,100%)

パラメータは引数、結果は戻り値と言います。引数や戻り値がない関数もあります。~
例としてfd_printf文を紹介します。

***fd_printf文 [#k44284d5]
文字や変数の値などを[[Chapter1.2>FDIIICHAPTER1.2]]でインストールしたSIMPLE TERM上で表示する時に使います。~

通常のC言語ではprintfと書きますが、FREEDOMライブラリではfd_printfと書きます。
#ref(printf1.png,100%)
fd_printfの () 内の " で挟まれた文字をそのまま表示しています。
----
#ref(printf2.png,100%)
aという変数の値を表示しています。変数の値をどのように表示するかは " " 内の%dの部分で指定します。%dの部分に何を表示するかを " " の後に , で区切って書きます。~
fd_printf文で使用できる書式は以下の通りです。~
| 書式指定 | 意味 | 例 |
| %d | 整数を10進数で表示 | 5, -17 など |
| %c | 文字 | 単一の'G' など |
| %s | 文字列 | "Hello" など |
| %o | 整数を8進数で表示 | 12, 23 など |
| %b | 整数を2進数で表示 | 10, 1011 など |
| %u | 整数を符号なし10進数で表示 | 37, 2093 など |
| %x | 整数を16進数で表示 | 1A, B89E など |

----
#ref(printf3.png,100%)
%とdの間に入る数値は桁数を表します。空いている桁にはスペースが入ります。~
さらに数値の前に0を付けると空いている桁には0が入ります。~

 \n
は改行です。その他に
 \r
と書くと復帰(同じ行の頭から再び表示する)になります。

|CENTER:BGCOLOR(red):||c
|&nbsp; :idea:|お使いのブラウザ(Internet Explorer、Firefox、Safariなど)によっては、文中の¥(円記号)が\(バックスラッシュ)で表示される場合がありますが、GCC Developer Liteでは¥で表示されます。&br;また本文中のプログラムコード(プログラムを書いたもの)をGCC Developer Liteへコピーして貼り付けた場合、\は¥になりますので問題ありません。&br;※説明のためここでは¥と\を全角で書いていますが、実際には半角です。|
[[こちら>FDIIILIB]]でFDIII-HCで使用できる関数を紹介しています。~

**プログラムの書き方 [#s49216c9]
プログラムは唯でさえ英語が並んで読みにくいものです。暫くたって読み返す時や他人に見せる時に分かりやすいように書く必要があります。~
自分で書き方を統一して書くとより分かりやすくなります。
***インデント(字下げ) [#x04982a4]
#html{{
<pre class="brush: c">
 #include &lt;fd.h&gt;
 void main (void) {
   int i;
   for (i = 0, i < 5; i++) {
     if (i > 3) {
       fd_printf ("%d\n", i);
     }
   }
   while (i++ < 10) {
     fd_putc ('.');
   }
 }
</pre>
}}
各関数内にインデントを付け、階層化することで、それぞれの関数の開始位置と終了位置が分かりやすくなります。

[[FDIII-HC Starter Kit Guide>LEARNINGGUIDE]]に戻る

« Prev[3]