初心に立ち返り、C言語を復習する①

初心に立ち返る意味を込めて、数年ぶりにC言語を復習したのでその記録です。
自分なりにまとめています。

至らぬ点があるかもしれませんが、ご容赦ください。

# 環境について

|種別|バージョンなど|
|:---:|:---:|
|ハードウェア|Macbook Air (Early 2015)|
|OS|macOS Mojave (10.14.1)|
|コンパイラ|GCC (4.2.1)|
|エディタ|Atom (1.32.2)|

Atomのプラグインとして、ターミナル、linterなどのプラグインを導入しています。（これはお好みで）

# まずはHello world

## ソースコード
```C:hello.c
#include <stdio.h>

int main(int argc, char const *argv[]) {
  printf("Hello world!\n");
  return 0;
}
```

## コンパイル
```
gcc -o hello hello.c
```
gccコマンドの後に、"-o hello hello.c"としているのは、hello.cというソースファイルをhelloという実行ファイルを出力しますよという意味になります。
(他のオプションなど詳しくは、"gcc オプション"で検索するといいかも)

ちなみに、このオプション(引数)を指定せず、gcc hello.cとした場合は、a.outという実行ファイルが生成されます。

## 実行
```
./hello

>実行結果
Hello world!
```

# 


# 簡単なじゃんけんゲームを作成する
## じゃんけんゲームにした理由
構造化定理(順次、分岐、繰り返し)に基づく制御文を網羅でき、コマンドラインへの入出力の仕方等を習得できるためです。
### 順次
記述された順（上から下、左から右）に、プログラムが実行される。
### 分岐(if文、switch-case文)
条件によって、処理が分かれる。
例) ユーザーからの入力によって、処理を変えたい。
### 繰り返し(for文、while文)
条件を満たしている間、または満たすまでの間処理を繰り返す。
例) ○回勝負のように何度か繰り返す処理を行いたい。

##要件定義
大雑把ですが・・・

- コンピューターとユーザーで、じゃんけんの対決が行えること。
- ユーザーからの入力は、1〜3の数字などの入力とする。
- コンピュータの手は毎回違うもの(ランダム)とする。(ただし、コンピューター側はインチキをしないこと)
- 最後に勝率を求められるものとする。

## ソースコード
```c:janken.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROCK 1
#define SCISSORS 2
#define PAPER 3
#define GAME_CNT 3

int main(int argc, char const *argv[]) {
  int user_input;           //ユーザーの入力
  int com_input;            //コンピューターの入力
  float points = 0;         //ユーザーが勝った回数
  float winning_percentage; //ユーザーの勝率
  int i;                    //n回勝負を実現するためのループカウンタ

  for(i = 0; i < GAME_CNT; i++)
  {
    //ユーザーの入力
    printf("%d回目 手を入力してください(グー:1  チョキ:2  パー:3) : ", i + 1);
    scanf("%d", &user_input);
    //コンピューターの入力(乱数を使用する)
    srand((unsigned int)time(NULL));  //srand関数によって、毎回異なる乱数を生成する
    com_input = rand() % 3 + 1; //1〜3の乱数を発生させる

    //ユーザー・コンピュータの入力に基づき、勝敗判定
    switch (user_input)
    {
      //グーの場合
      case 1:
      if(com_input == 1)
      {
        printf("コンピューター : グー\n");
        printf("あいこ\n");
        points += 0.5;
      }
      else if(com_input == 2)
      {
        printf("コンピューター : チョキ\n");
        printf("勝ち\n");
        points += 1.0;
      }
      else if(com_input == 3)
      {
        printf("コンピューター : パー\n");
        printf("負け\n");
      }
      break;

      //チョキの場合
      case 2:
      if(com_input == 1)
      {
        printf("コンピューター : グー\n");
        printf("負け\n");
      }
      else if(com_input == 2)
      {
        printf("コンピューター : チョキ\n");
        printf("あいこ\n");
        points += 0.5;
      }
      else if(com_input == 3)
      {
        printf("コンピューター : パー\n");
        printf("勝ち\n");
        points += 1.0;
      }
      break;

      //パーの場合
      case 3:
      if(com_input == 1)
      {
        printf("コンピューター : グー\n");
        printf("勝ち\n");
        points += 1.0;
      }
      else if(com_input == 2)
      {
        printf("コンピューター : チョキ\n");
        printf("負け\n");
      }
      else if(com_input == 3)
      {
        printf("コンピューター : パー\n");
        printf("あいこ\n");
        points += 0.5;
      }
      break;

      //ユーザーが1〜3以外の数字を入力した場合
      default:
      printf("1〜3の数字を入力してください\n");
      continue;
    }
  }
  //勝率計算処理
  winning_percentage = points / GAME_CNT * 100;
  printf("勝ち点 : %3.1f  勝率 : %5.2f %% \n", points, winning_percentage);
  return 0;
}
```

## 実行結果
```
1回目 手を入力してください(グー:1  チョキ:2  パー:3) : 2
コンピューター : チョキ
あいこ
2回目 手を入力してください(グー:1  チョキ:2  パー:3) : 1
コンピューター : チョキ
勝ち
3回目 手を入力してください(グー:1  チョキ:2  パー:3) : 3
コンピューター : グー
勝ち
勝ち点 : 2.5  勝率 : 83.33 %
```
## 反省点
勝敗判定部分のロジックをもう少し簡素化できるといいのですが・・・。

# まとめ
しばらくプログラミングから遠ざかっていたので、”プログラマー勘”のようなものを取り戻す一環としてC言語を復習してみました。
ロジックを考える時間は楽しいものの、長らくやってなかったのでなかなか思い浮かばなく、リハビリが必要そうです。

最後までご覧頂き、ありがとうございました。