Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

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

環境について

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

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

まずはHello world

ソースコード

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の数字などの入力とする。
  • コンピュータの手は毎回違うもの(ランダム)とする。(ただし、コンピューター側はインチキをしないこと)
  • 最後に勝率を求められるものとする。

ソースコード

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言語を復習してみました。
ロジックを考える時間は楽しいものの、長らくやってなかったのでなかなか思い浮かばなく、リハビリが必要そうです。

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

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away