#4 C言語のキホン➀【もっと!後輩たちのためのEV3rt講座】

# 目次

| 章 | タイトル | 内容 |
| :-: | :-: | :-: |
| 1 | [はじめに](#1-はじめに) | 今回やることの説明 |
| 2 | [main_task について](#2-main_task-について) | main_taskの動きについて説明 |
| 3 | [演算子の使い方](#3-演算子の使い方) | 演算子の使い方について説明 |
| 4 | [変数の使い方](#4-変数の使い方) | 変数の使い方について説明 |
| 5 | [配列の使い方](#5-配列の使い方) | 配列の使い方について説明 |
| 6 | [関数とは](#6-関数とは) | 関数について簡単に説明 |
| 7 | [まとめ](#7-まとめ) | 今回のまとめ |

# 1. はじめに

前回はEV3rtで開発する際のお約束事について確認しました。
今回からいよいよ、プログラム書いていきたいと思います。

ただ、まだモータやセンサは動かしません…
まずは、EV3rtの開発言語であるC言語について、基本的な事項のみですが確認していきたいと思います。
詳しい文法についてはC言語の本やサイトを確認するようにしてください。

## 参考書籍

[新・明解C言語 入門編 第2版 単行本](https://amzn.asia/d/dP2I1o8)

[Cの絵本 第2版 C言語が好きになる新しい9つの扉](https://amzn.asia/d/6snZZj8)

## 参考サイト

[C言語入門 | Let'sプログラミング](https://www.javadrive.jp/cstart/)

[苦しんで覚えるＣ言語](https://9cguide.appspot.com/index.html)

# 2. main_task について

まずは、前回作成した`temp`プロジェクトの`app.c`を開いてみましょう。

```c:app.c
#include "ev3api.h"
#include "app.h"
#include <stdio.h>

void main_task(intptr_t unused)
{
    //プログラムをここから書く
}
```

前回もお伝えしたように、プログラムが動き始めると`main_task`関数の中を上から順番に実行していきます。
(ただし、`app.cfg`でタスクの設定を変更した場合はこの限りではありません。)

基本的には、この`main_task`の`{` `}`の中にプログラムを書いていけば良いということになります。
(関数や変数など外に書く場合がありますが、それについては追々紹介します。)

# 3. 演算子の使い方

EV3ソフトウェアには、以下のような「数学ブロック」がありました。

![EV3soft_var3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/2849b52d-2f73-be8a-9d04-68a05acb89a3.png)

C言語でのプログラミングでも、このような演算を多用するので、その方法を押さえておきましょう。

## 算術演算子 (さんじゅつえんざんし)

計算を行う為の演算子を「算術演算子」(さんじゅつえんざんし)と言います。
EV3ソフトウェアでの例と比較してみましょう。

![EV3soft_var4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/a5dabd2d-6ea1-be3c-49a8-85c5c4da4109.png)

| 演算子 | 名前 | 記述例 | 意味 |
| :-: | :-: | :-: | :-: |
| + | 加算 | a + b | a に b を加える |
| - | 減算 | a - b | a から b を引く |
| * | 乗算 | a * b | a に b をかける |
| / | 除算 | a / b | a を b で割る |
| % | 剰余 | a % b | a を b で割った余り |

[C言語入門 | Let'sプログラミング / 算術演算子 / 算術演算子の種類](https://www.javadrive.jp/cstart/ope/index1.html) より引用

## 代入演算子 (だいにゅうえんざんし)

次に、この後紹介する「変数」に値を代入するときに使用する「代入演算子」(だいにゅうえんざんし)について記します。

例えば、EV3ソフトウェアで以下のようにブロックを組むと、`2 + 3`の計算結果`5`が、変数`a`に代入されますよね。

![EV3soft_var5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/244385d2-16a3-85c9-c1eb-14b448bc2f20.png)

これでいう黄色の線が、「代入」にあたるわけですが、これをC言語では代入演算子`=`(イコール)を用いて、以下のように表します。

```c
int a = 2 + 3;
```

`=`の左側が「代入される先」、右側が「代入する値」ということになります。

## 代入演算子と算術演算子

さて、変数に何か値を加算したいとき、EV3ソフトウェアでは以下のようにブロックを組んでいました。

![EV3soft_var6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/f9ec493a-9e3d-347b-faf1-6d948b352279.png)

これをC言語で表すと以下のようになるわけですが…

```c
int a = 1;
a = a + 1;
```

このコードの2行目の部分は、以下のように省略することができます。

```c
int a = 1;
a += 1;
```

C言語にはこのように省略できる代入演算子が用意されています。
コードを短く、かつ分かりやすく書くことができるので、慣れてきたら有効的に使っていきましょう。

| 演算子 | 記述例 | 意味 |
| :-: | :-: | :-: |
| += | 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 |

[C言語入門 | Let'sプログラミング / 算術演算子 / 代入演算子と算術演算子の組み合わせ](https://www.javadrive.jp/cstart/ope/index1.html) より引用・抜粋

## インクリメント演算子・デクリメント演算子

もう一つ、省略できる演算子を紹介します。

先ほど、変数`a`に`1`を加算するコードを示しました。

```c
int a = 1;
a = a + 1;
```

前の章では代入演算子を説明するために`+=`を使いましたが、「ある変数に対して`1`加算する」といった場合は、「インクリメント演算子」というものを使うことができます。

```c
int a = 1;
a++; // a = a + 1; や a += 1; と同じ意味
```

この`+`を2つ重ねた形`++`がインクリメント演算子で、上の例でいえば変数`a`に`1`加算します。

同様に「ある変数に対して`1`減算する」といった場合は、「デクリメント演算子」というものを使うことができます。

```c
int a = 1;
a--; // a = a - 1; や a -= 1; と同じ意味
```

この`-`を2つ重ねた形`--`がデクリメント演算子で、上の例でいえば変数`a`から`1`減算するので、`a`の値は`0`になります。

このインクリメント演算子・デクリメント演算子ですが、今後紹介する「ループ処理」で多用するので、意味だけでも覚えておきましょう。

# 4. 変数の使い方

## 変数とは

「変数」とは、簡単に言えば「値を保管するための箱」です。

イラストで表すとこんな感じ👇

![variable.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/4ed7dca2-aa3f-6534-77eb-c29e07ed4bb3.gif)

又、EV3ソフトウェアでは以下のようにして使用していました。

![EV3soft_var.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/372976c7-d406-66bf-e865-bb0da70f353a.png)

ロボットを動かす時で言えば、センサの値を保持したい時など、変数は様々なところで使われ、プログラムに必要不可欠な要素です。

## 型について

さて、C言語で扱うあらゆるデータには **型(かた)** というものが存在します。

例えば、数値としての`2`と、文字としての`'2'`は全くの別物です。

EV3ソフトウェアにおいても、以下の二つ「`a`の数値」と「`b`のテキスト」は違うものでしたよね。

![EV3soft_var2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/b9b456af-2319-74d0-a030-8d50dfbbfaff.png)

C言語では、上記のような「数値として扱うデータ」や「文字として扱うデータ」を **「型」(かた)** として指定します。
この「型」を混同してプログラムを作成すると、思わぬバグを生み出すことにつながりかねないので、注意しましょう。

「型」は **変数の宣言** の時や、後ほど紹介する「関数の引数・戻り値」のデータ形式の指定に使われます。

ひとまず、EV3rtでよく使う以下の3つの「型」を覚えておきましょう。

| 型名 | 表現出来るデータ |
| :-: | :-: |
| int | 整数値 |
| double | 小数値 |
| char | 文字 |

## 宣言

上記の型を用いて、変数を「宣言」してみましょう。
「宣言」とは、新しく変数を作成することを言います。
それぞれ、以下のように宣言します。

```c
int a;
int b = 5;

double x = 0.01;

char s = 'a';
```

まず一行目のように、箱を作成するだけしておく、ということができます。
この場合、`a`という名前で、整数値を入れることが出来る箱を、作るだけ作っておきました、という状態です。
中身については決まっていませんので、読み出す前に何かしらの値を入れる必要があります。

二行目のように、名前の後に`=`をつけて値を指定すると、箱を作成し、さらにその中に値を入れておくことが可能となります。
この場合、`b`という名前で、整数値を入れることが出来る箱を作り、さらにその中身は`5`であると指定しています。

四行目は、小数点以下が含まれる数値を扱うときの変数の宣言方法です。
`int`型はあくまで整数値しか扱えませんので、小数値を扱う場合は`double`型が必要です。

六行目は、文字を扱うときの変数の宣言方法です。
上述の通り、数値データと文字データは全くの別物ですので、この場合は文字データ型である`char`型を用います。

# 5. 配列の使い方

さて、前の章で変数とは「値を保管するための箱」と説明しました。
「配列」とは「変数(値を保管するための箱)を横にいっぱい並べたもの」と言えるでしょう。

イラストで説明すればこんな感じ👇

![list.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/9d6cf438-42b5-c38b-b086-c714701410a4.gif)

変数では一つの箱につき一つの値しか入れることが出来ませんでしたが、配列はその箱がいくつも連なり部屋のようになっているので、それぞれの部屋に値を代入することができます。

その部屋についてですが、正しくは「インデックス」と言います。
要するに「部屋番号」ということです。

配列から値を読み出す、もしくは配列に値を書き込むときは、「配列名」と「インデックス」を指定します。

この「インデックス」ですが、 **0から始まる** ことに注意してください。

もちろん、配列にも「型」の指定が必要なので注意してください。

## 宣言

それでは、配列を宣言してみましょう。

こちらもEV3ソフトウェアと比較しながら見ていきます。

![EV3soft_list1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/ef199cec-4f17-a7d2-f88b-989d21a6c8e1.png)

```c
int a[5];

int b[5] = {1, 3, 5, 7, 9};
```

1行目の例は、配列名`a`、部屋の数が`5`の配列を、作るだけ作ったという状態です。

3行目の例は、宣言と同時に値の代入も行っており、部屋番号`[0]` には値`1`、部屋番号`[1]`には値`3`、・・・といった具合に値が代入されています。

## 書き込み・読み出し

配列に値を書き込む方法、および値を読み出す方法を記しておきます。

これに関しても、EV3ソフトウェアでの例を提示しておきます。

![EV3soft_list2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/094cc0ea-aca0-affe-a4ef-2dbfdeb0a790.png)

```c
int a[5] = {2, 4, 6, 8, 10};

a[1] = 3;
int x = a[2];
```

1行目が配列の宣言であり、3行目が書き込み(代入)の方法、4行目が読み出しの方法です。

どちらも「配列名」と「インデックス」を指定して使用します。

3行目の例でいえば、配列`a`の部屋番号`[1]`の部屋に、値`3`を代入します。

一方4行目の例でいえば、配列`a`の部屋番号`[2]`の部屋の値(今でいうと`6`)を、変数`x`に代入します。

EV3ソフトウェアと比較して、配列の扱いはむしろ簡単だと私は感じているので、積極的に活用していきましょう。

## 文字列について

ここで、C言語における **「文字列」** の扱いについて記しておきます。
先ほど変数の章にて、文字の型は`char`であると説明しました。
しかしこの`char`型ですが、正しくは「単一文字」のデータ型となり、2字以上からなる「文字列」を扱うことができません。

そこで、C言語では配列を使って文字列を表現します。
例えばこんな感じ👇

```c
char str[] = "Hello EV3rt!!";
```

`Hello EV3rt!!`はスペースを含めて全部で13文字ですが、実際には文字列の一番最後に「ここが終わりですよ～」という印が一文字分入ります。(`\0`のNULL(ヌル)文字と言います。)

従って配列`str`は、`13 + 1 = 14` より長さ14の`char`型配列となります。

![str.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/b78d6637-cf5e-d024-5942-c14b21780434.png)

EV3rtでのプログラム開発においては、インテリジェントブロックのLCD(液晶画面)に文字を表示したい時などに文字列を使用することがあります。
C言語では文字列をこのように表現することを頭の片隅入れておくと良いかと思います。

# 6. 関数とは

「関数」というものを簡単に説明したいと思います。
定義を含めた詳しい活用法は別の回に紹介します。

関数を一言で説明すれば、「ある値を入れた時に、決められた法則に基づいて値を返してくれる機能」です。

イラストで表すとこんな感じ👇

![func.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/09795274-b6df-f612-c257-cd9f99538ea4.gif)

上の図に表すように、関数にいくつかの値を入れます。
この値のことを **「引数」(ひきすう)** と言います。

引数を受け取った関数は、決まった法則に基づいて処理を行います。

その結果得られた値を **「戻り値」** として返します。

例えば、以下のような「足し算を行う関数」があるとします。

```c
int sum(int a, int b){
  return a + b;
}
```

関数の名前が`sum`で、引数は`a`と`b`の二つです。
意味としては引数として受け取った`a`と`b`の値を足し合わせて、戻り値として返すというものです。

よって、以下のように関数を実行すると…

```c
int c = sum(2,3);
```

変数`c`には`5`が入るということになります。

尚、「引数」や「戻り値」は、必要ない場合省略することも出来ます。
これも追々説明していきたいと思います。

さて、`a`や`b`の前、さらに`sum`の前に **`int`** という文字があります。
ここでも、データの「型」が指定されています。

引数として整数値`a`と整数値`b`を受け付けて、`a+b`の結果を整数値で返す、という意味になります。

## EV3rtのAPI

ここで、EV3rtの**API** (Application Programming Interface) について確認したいと思います。
APIとは、アプリケーションを簡単に作成するために用意されている機能です。
EV3rtのAPIとしては「モータを動かす関数」や、「センサで値を取得する関数」が定義されています。

APIは以下のリンク👇から確認できます。

https://www.toppers.jp/ev3pf/EV3RT_C_API_Reference/index.html

使い方は上の足し算関数の例と同じです。

例えば、今後紹介する「モータのパワーを設定する関数」は以下の通りです。

```c
ev3_motor_set_power(EV3_PORT_A, 50);
```

関数名が`ev3_motor_set_power`で、「引数」としてポート名`EV3_PORT_A`とパワー`50`を与えており、ポートAに接続されたモータがパワー50%で動くようになっています。
この場合、「戻り値」の扱いは省略されていますね。

(厳密には、その関数が正常に動作したかのエラーコードが戻り値として返って来てはいます。)

又、以下はカラーセンサを用いて反射光を得るコードは以下のようになります。

```c
int ref = ev3_color_sensor_get_reflect(EV3_PORT_1);
```

この場合、引数としてポート名`EV3_PORT_1`を指定しており、ポート1に接続されたカラーセンサから反射光の値を戻り値として返しています。
戻り値は変数`ref`に格納されることになります。

このようにAPIで定義された関数を用いていくので、覚えておきましょう。

# 7. まとめ

今回はC言語のキホン➀ということで、演算子、変数、配列、関数について簡単に説明してきました。
本記事ではEV3rtでプログラミングするにあたり、最低限必要なことしか書いていませんので、もっと詳しく知りたい、ここに書かれていない文法を使いたい、という場合は冒頭にも記した通り、C言語の書籍やサイトを読んでみてください。

次回もC言語のキホン➁と題し、制御構文(分岐やループなど)について記して行きたいと思います。

前回: [#3 アプリケーション開発のおやくそく](https://qiita.com/koushiro/items/e3d04e3a4e266c603865)
次回: [#5 C言語のキホン➁](https://qiita.com/koushiro/items/9ee84c3b5bdefc0475c8)