LIFE LOG(ここにはあなたのブログ名)

あつあつ備忘録

ソフトやハード、時にはメカの備忘録をまとめていきます

【C/C++第3回】ループ処理・配列

f:id:AtsuyaKoike:20181203020624p:plain

今回学習する内容はループ処理(繰り返し処理)です。
これの主な用途としては、同じ処理を一定回数繰り返したい場合などに使用されます。
たとえば「LEDを3回点滅させたい」と思ったときに

led = 1;
wait(1);
led = 0;
wait(1);
led = 1;
wait(1);
led = 0;
wait(1);
led = 1;
wait(1);
led = 0;
wait(1);

と書くのはプログラムが無駄に長くなり見た目も悪いわけですね。そのためにループ処理というものを行います。
ループをする際に主に使われる関数はforとwhileです。それでは実際に使っていきましょう。

for
とりあえず「Hello, world」を5回表示させるサンプルプログラムを載せたいと思います。

#include<stdio.h>
int main(int argc,char *argv[])
{
    int i, Num;
    Num = 5; 
    for(i = 0; i < Num; i++)
    {
        printf("Hello, world!\n");
    }
    return 0;
}

これがfor分の使い方になります。

for(i = 0; i < Num; i++)
{
    printf("Hello, world!\n");
}

まず、i=0は、iに0を代入しています。
i++の部分では、1周するたびにiを1ずつインデント(増やしていく)ことを意味します。
i < Numの部分では、iがNum以下の場合にfor文の中身を実行していくことを示します。

とりあえず実行してみましょう。今回はprogram1.cというファイル名にしました。

PS D:\C> gcc -o program1 program1.c
PS D:\C> ./program1
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!

無事、Hello, worldが実行されていますね。プログラム中のNumの値を5から10や15に変更して実行してみてください。

このプログラムを弄って、いくつめのHello, worldなのかすぐにわかるようにしたいと思います。
出力イメージ

0 Hello, world
1 Hello, world
:
9 Hello world

上記プログラムを

printf("Hello, world!\n");

から

printf("%d Hello, world!\n", i);

に変更してみてください。すると実行結果が以下のようになります。

PS D:\C> gcc -o program1 program1.c
PS D:\C> ./program1
0 Hello, world!
1 Hello, world!
2 Hello, world!
3 Hello, world!
4 Hello, world!

最も左側に番号がふられていることが分かりますね。このようにしてループ処理を行うことができます。

while
まず最初にwhile文を使ったサンプルプログラムを載せたいと思います。

#include<stdio.h>
int main(int argc,char *argv[])
{
    int i=0;
    while(1)
    {
        if( i >= 5 )
        {
            break;
        }
        printf("%d Hello, world!!\n", i);
        i++;
    }
    return 0;
}

実行結果

0 Hello, world!!
1 Hello, world!!
2 Hello, world!!
3 Hello, world!!
4 Hello, world!!

実行結果はfor文を使ったものと同じになりましたね。上から解説していきます。

int i = 0;

この部分では、iという変数を宣言して0を代入しています。これを「0で初期化する」といいます。なぜ初期化するのかは後で説明します。

while(1)

ソフトウェアにおいて1は真、0は負を示します。
上記の通り、whileはループ処理をする関数でしてfor文のように条件式がありません。つまりこれは無限ループを意味しているのです。永久に動作を繰り返す場合、何かアクションがあるまで動作する場合などに使用します。しかしHello, world!!という出力は5つしかありませんね。これはどういうことかというと

if( i >= 5 )
{
        break;
}

が鍵を握っています。これは、if文というものを使用しています。ifの条件式を満たしたときにif文の中を実行します。つまりiの値が5以上になったときにbreakします。
breakすることでwhile文から抜け出すことができるのです。今回はiの値でbreakさせましたがハードウェアを使用した場合に、センサやスイッチの値を見るなどしてbreakすることが多いです。

次に、配列というものを扱います。
例えば、変数aとbとcがあった場合は、下の図の上の様な箱をイメージして考えることができます。
しかし、aという配列を宣言した場合は下の図の下のような箱をイメージして考えます。
f:id:AtsuyaKoike:20181214150724p:plain:w300

これの何が便利かというと、数字の合計を求めたり、決まったパターンで動くものなら配列を使うだけで扱いが非常に楽になります。
実際に例を示したいと思います。

#include<stdio.h>
int main(int argc, char *argv[])
{
    int a[10], i, sum=0;
    for(i = 0; i < 10; i++)
    {
        printf("input:");
        scanf("%d", &a[i]);
        sum += a[i];
    }
    printf("sum = %d", sum);
    return 0;
}

このプログラムを使用して、入力された合計10個の数字の和を求めることができます。配列を知らない場合だとしたらscanf()を10回書いていたところだと思いますが、配列を使うことでこんなにもコンパクトで分かりやすいプログラムになりました。
解説としては、変数宣言の方法を

int a[10];

のように、[]を使用して、その中に使用したい要素数(箱の数)を記入します。そしてループ内でインデントしているiで何個目の要素(箱)を使用するかを決めています。

次にあらかじめ配列に値を入れておいて、それを使用するプログラムを使ってみようと思います。

#include "mbed.h"
DigitalOut myled(PB_3);

int main()
{
    int a[10]={ 1, 0, 1, 0, 1, 1, 0, 0, 1, 0 };
    int i=0;
    while(1)
    {
        if ( i >= 10 ) {
            i = 0;
        }
        myled = a[i];
        wait(0.5);
        i++;
    }
}

あらかじめ、LEDの点滅パターンが決まっている場合にこのように配列を使用します。
(実際にはブザーで音階を表現するときや7セグメントLEDを使用するときによく使います)。

今日は以上になります。
以下、来週までの宿題です。
①mbed compilerの登録
mbed Compiler - Handbook | Mbed
②USBケーブルをSTM32(Nucleo)につないだ際に基板上のLEDがチカチカするかの確認。
f(x) = \sum_{i=0}^{100} iのf(x)を求めるプログラム作成