4: 2011-06-27 (月) 21:13:53 yoshida | 現: 2011-08-09 (火) 20:23:18 takaboo | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | TITLE:FDIII-HC Starter Kit Guide Capter1.4 | ||
*C言語の基礎 [#pcd8150f] | *C言語の基礎 [#pcd8150f] | ||
- | このページではFREEDOMライブラリを使用した場合のC言語について説明をします。~ | + | このページでは[[FREEDOM IIIライブラリ>FDIIILIB]]を使用した場合のC言語について説明をします。~ |
- | 通常のC言語と若干異なる場合があります。 | + | |
**基本 [#f828bd2e] | **基本 [#f828bd2e] | ||
Line 35: | Line 33: | ||
1バイトで表すことができる数値は10進数で表すと0~255です。 | 1バイトで表すことができる数値は10進数で表すと0~255です。 | ||
- | 下表は10進数を2進数(1バイト)で表した例です。 | + | 下表は10進数を2進数で表した例です。 |
- | | 10進数 | 2進数(1バイド) | | + | | 10進数 | 2進数 | |
| 0 | 00000000 | | | 0 | 00000000 | | ||
| 50 | 00110010 | | | 50 | 00110010 | | ||
Line 42: | Line 40: | ||
| 200 | 11001000 | | | 200 | 11001000 | | ||
| 255 | 11111111 | | | 255 | 11111111 | | ||
+ | |||
***変数 [#h0d4cb7f] | ***変数 [#h0d4cb7f] | ||
変数は数値や文字を置いておく入れ物です。~ | 変数は数値や文字を置いておく入れ物です。~ | ||
Line 54: | Line 53: | ||
***データ型 [#p7400a94] | ***データ型 [#p7400a94] | ||
変数は使い始める前に「このようなデータを入れるこんな名前の入れ物を使います」と予め宣言しておかなければなりません。「このようなデータ」を型と言います。~ | 変数は使い始める前に「このようなデータを入れるこんな名前の入れ物を使います」と予め宣言しておかなければなりません。「このようなデータ」を型と言います。~ | ||
- | 型には以下があり、それぞれサイズと入る値の範囲が異なります。 | + | FDIII-HCを使用する際のデータ型には以下のように、それぞれサイズと入る値の範囲が異なります。 |
- | | 型の名前 | サイズ | 入る値の範囲 | | + | | 型の名前 | サイズ | 入る値の範囲 | 備考 | |
- | | char | 1バイト | -128~127 | | + | | int8_t | 8ビット | -128~127 | 8ビット指定 | |
- | | unsigned char | 1バイト | 0~255 | | + | | char | 8ビット | -128~127 | | |
- | | short | 2バイト | -32768~32767 | | + | | uint8_t | 8ビット | 0~255 | (8)ビット指定 | |
- | | unsigned short | 2バイト | 0~65535 | | + | | unsigned char | 8ビット | 0~255 | | |
- | | long | 4バイト | -2147483648~2147483647 | | + | | int16_t | 16ビット | -32768~32767 | 16ビット指定 | |
- | | unsigned long | 4バイト | 0~4294967295 | | + | | short | 16ビット | -32768~32767 | short int | |
- | | int | 4バイト | -2147483648~2147483647 | | + | | uint16_t | 16ビット | 0~65535 | 16ビット指定 | |
- | | unsigned int | 4バイト | 0~4294967295 | | + | | 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 | | | ||
変数は数値や文字を置いておく入れ物でした。 | 変数は数値や文字を置いておく入れ物でした。 | ||
大きい入れ物なら大きな数字も入れられるので、変数のサイズが大きい型を選べば良いと思うかもしれません。 | 大きい入れ物なら大きな数字も入れられるので、変数のサイズが大きい型を選べば良いと思うかもしれません。 | ||
- | しかしコンピュータが大きいサイズの変数を扱うには、小さいサイズの変数に比べて記憶しておく場所も大きくなり、それに伴う様々な処理にかかる時間も必要になってきます。~ | + | しかしコンピュータが大きいサイズの変数を扱うには、小さいサイズの変数に比べて記憶しておく場所も大きくなり、それに伴う様々な処理にかかる時間も必要になってきます。 |
- | ~ | + | |
- | unsignedの付いている型はマイナスを扱うことができませんが、表すことでのできる最大値は倍となります。~ | + | |
***演算子 [#k3be0d0f] | ***演算子 [#k3be0d0f] | ||
Line 83: | Line 86: | ||
算数でa=bは、aとbは同じという意味で使うのが一般的ですが、C言語では右辺を左辺に代入します。例えばa=2を左辺、b=3を右辺とし、a=bにすると、bの値がaに代入されa、b両方とも3になります。このため、代入演算子と呼ばれています。~ | 算数でa=bは、aとbは同じという意味で使うのが一般的ですが、C言語では右辺を左辺に代入します。例えばa=2を左辺、b=3を右辺とし、a=bにすると、bの値がaに代入されa、b両方とも3になります。このため、代入演算子と呼ばれています。~ | ||
- | その他の四則演算に加え、余りを出す演算子を合わせて算術演算子と呼びます。 | + | 四則演算に加え、余りを出す演算子を合わせて算術演算子と呼びます。 |
その他に以下の演算子があります。 | その他に以下の演算子があります。 | ||
Line 95: | Line 98: | ||
| ++ | a++ | a = a + 1 | | | ++ | a++ | a = a + 1 | | ||
| -- | 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] | ***比較演算子 [#db59b61c] | ||
Line 125: | Line 156: | ||
#html{{ | #html{{ | ||
<pre class="brush: c"> | <pre class="brush: c"> | ||
- | #include <fd.h> | ||
- | void main (void) { | ||
int a, b = 3; | int a, b = 3; | ||
- | fd_Wait (2000); | ||
a = &b; | a = &b; | ||
- | printf ("a=%d\n", a); | ||
- | } | ||
</pre> | </pre> | ||
}} | }} | ||
- | a=2103864 | ||
aには3ではなく、bのアドレスの値が入ります。~ | aには3ではなく、bのアドレスの値が入ります。~ | ||
- | ***ポインタ [#de8fd791] | + | ***配列とポインタ [#de8fd791] |
- | アドレスを利用する別の方法としてポインタがあります。~ | + | アドレスを利用するには配列とポインタをしっかりと学ぶ必要があります。~ |
- | char *a = "BEST"; | + | ****配列とは [#ze3b2962] |
- | 以上がchar型のポインタ宣言となります。BESTという文字列はメモリ上のどこかに格納されており、そのアドレスを示しているのがポインタです。~ | + | 配列はその変数の型の配列数分メモリ領域を確保します。確保された配列上は型さえ一致すれば何を代入しても問題ありません。~ |
- | BESTという文字列を操作するにはアドレスを介して操作するしかありません。そのため、*を間接演算子と呼びます。~ | + | 宣言方法は以下の通りです。 |
- | 以下にアドレス演算子を使用した場合と比較してみます。 | + | #html{{ |
- | | 状態 | アドレス演算子 | 間接演算子 | | + | <pre class="brush:c"> |
- | | 宣言 | int a; | int *a; | | + | char a[5] = "BEST"; |
- | | アドレスを渡す | b = &a; | b = a; | | + | </pre> |
- | | 内容を渡す | b = a; | b = *a; | | + | }} |
+ | #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 <fd.h> | ||
+ | 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が付与されて初めて文字列として扱われます。~ |
- | | 00112239 | B |アドレスは例です | | + | |
- | | 0011223A | E | | | + | |
- | | 0011223B | E | | | + | |
- | | 0011223C | T | | | + | |
- | | 0011223D | Null |最後にNULLがセットされます | | + | |
- | BESTは、文字としては4文字ですが、メモリ上は5バイト確保されます。C言語ではBESTは只の文字データであり、文字列ではありません。BESTの最後にNULLが付与されて初めて文字列として扱われます。~ | + | |
つまり~ | つまり~ | ||
char *a = "BEST"; | char *a = "BEST"; | ||
は~ | は~ | ||
char a[5] = { 'B', 'E', 'S', 'T', NULL }; | char a[5] = { 'B', 'E', 'S', 'T', NULL }; | ||
- | と同じです。~ | + | と同じことです。~ |
- | このため、配列として扱い、インデックスを使用することで、文字の取得が可能です。 | + | このため、配列として扱うことで、文字の取得が可能となっています。以下はbに'E'を代入します。~ |
#html{{ | #html{{ | ||
<pre class="brush: c"> | <pre class="brush: c"> | ||
char *a = "BEST", b; | char *a = "BEST", b; | ||
- | b = a[1]; // 2文字目を代入します(インデックスは0から開始) | + | b = a[1]; // 2文字目を代入します |
</pre> | </pre> | ||
}} | }} | ||
- | bにはEが代入されます。~ | + | ポインタを使用して文字の取得を行う場合は以下の通りです。~ |
- | ポインタを使用して文字の取得を行うことも可能です。~ | + | |
#html{{ | #html{{ | ||
<pre class="brush: c"> | <pre class="brush: c"> | ||
Line 174: | Line 233: | ||
c = a; // アドレスをコピーします | c = a; // アドレスをコピーします | ||
c++; // アドレスを1つ進めます | c++; // アドレスを1つ進めます | ||
- | b = *c; // アドレスの示す内容を代入します | + | b = *c; // アドレスの示す内容(E)を代入します |
</pre> | </pre> | ||
}} | }} | ||
- | 配列として扱った時と同じように、bにはEが代入されます。~ | + | |
+ | **制御文 [#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 | ||
+ | | :idea:|お使いのブラウザ(Internet Explorer、Firefox、Safariなど)によっては、文中の¥(円記号)が\(バックスラッシュ)で表示される場合がありますが、GCC Developer Liteでは¥で表示されます。&br;また本文中のプログラムコード(プログラムを書いたもの)をGCC Developer Liteへコピーして貼り付けた場合、\は¥になりますので問題ありません。&br;※説明のためここでは¥と\を全角で書いていますが、実際には半角です。| | ||
+ | [[こちら>FDIIILIB]]でFDIII-HCで使用できる関数を紹介しています。~ | ||
+ | |||
+ | **プログラムの書き方 [#s49216c9] | ||
+ | プログラムは唯でさえ英語が並んで読みにくいものです。暫くたって読み返す時や他人に見せる時に分かりやすいように書く必要があります。~ | ||
+ | 自分で書き方を統一して書くとより分かりやすくなります。 | ||
+ | ***インデント(字下げ) [#x04982a4] | ||
+ | #html{{ | ||
+ | <pre class="brush: c"> | ||
+ | #include <fd.h> | ||
+ | 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]]に戻る |