はじめてのC++【13日目】

#はじめに
今日はAtcoderの振り返りとクラスの基礎をやります。
AとBは正解できましたがCは不正解でした。Dは手を付けていません。
##AtCoder
今日だけusing namespaceを解禁した。
### A問題 White Cells
>問題文
H行 W列の白色のマス目があります。あなたは h個の行と w個の列を選び、選んだ行または列に含まれるマス目を全て黒色で塗りつぶします。白色のマス目はいくつ残るでしょうか。なお、残る白色のマス目の数は行や列の選び方によらないことが証明できます。

```A.cpp
#include <iostream>
using namespace std;

int main()
{
  int H,W,h,w;
  int a,b;

  cin >> H >> W;
  cin >> h >> w;

  a = H - h;
  b = W - w;

  cout << a*b << endl;
}
```
この問題は問題は文は複雑でしたが、10分程度でクリアできて嬉しかったですね。

### B問題 Can you solve this?
<img width="898" alt="スクリーンショット 2019-03-09 23.47.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/597f8dcb-c6c3-9e58-b4ea-40f9a52cbdf6.png">

```B.cpp
#include <iostream>
using namespace std;

int main()
{
  int N;//行の数
  int M;//for文で回す
  int C;//最後に足す
  cin >> N >> M >> C;
  int B[20];
  int A[20][20];
  int count = 0;
  int ans = 0;

  //Bの値を決める
  for(int j = 0; j < M; j++)
  {
    cin >> B[j];
  }
  //Aの値を決める
  for(int i = 0; i < N; i++)
  {
    for(int j = 0; j < M; j++)
    {
      cin >> A[i][j];
    }
  }

  //正答するコード家計三
  for(int i = 0; i < N; i++)
  {
    for(int j = 0; j < M; j++)
    {
      ans += B[j]*A[i][j];
    }
    if(ans + C > 0) count++;
  
    ans = 0;//初期化
  }
  cout << count << endl;
}
```
この問題は60分ほどかかりなんとか正解できました。
std::arrayでやろうかなと思ったのですが、std::arrayの２次元配列がよくわからなかったので、普通の配列でやりました。要復習!

### C問題 Energy Drink Collector
<img width="913" alt="スクリーンショット 2019-03-09 23.50.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/f7c07dc5-4043-fd9c-4fbd-48318c93fe6a.png">

```C.cpp
#include <iostream>
#include <vector>
#include <algorithm> // sort
#include <map> // pair

using namespace std;
int main()
{
  int N;//i件目
  int M;//ほしいジュースのかず

  int a[1000];//pairの左
  int b[1000];//pairの右
  int money = 0;//使ったお金
  int num = 0;//ジュースを買った数
  vector<pair<int, int> > A;//動的配列生成


    for(int i = 0; i < N; i++)
  {
    cin >> a[i];
    cin >> b[i];
    A[i] = make_pair(a[i],b[i]);
  }

  sort( A.begin(), A.end());//a[]を小さい順にソート

  for(int i = 0; i < N; i++)
  {
    money = a[i]*b[i];//買った分だけお金を増やす
    num += b[i];//買った分だけ数を増やす
    if(num > M)//もしほしい数より買った数が大きくなったら
    {
      money -= (num - M) * a[i];//余分に買ってしまった分のお金を減らす
      break;//抜け出す
    }
  }
  cout << money << endl;
}
```
試験終了後にのる解説を見ながら考えましたが、正しくうごかない。
このコードだとコンパイルエラーはでない（Warningはたくさんでる）けど、実行したら、入力できずに0がターミナルに表示されるんですよね。c問題には、答えがないので、一旦おいておく。
##ロベールのC++
今日からクラスの基礎に入っていきます。クラス機能は開発にとって非常に重要なものになってくると聞いたので楽しみです。
###06-01　クラスの基本
クラスは構造体に少し似ている。しかし、クラスに```public```と書いて初めてメンバアクセスできるようになる。
クラスは構造体と同じように「型」である。そしてクラスの宣言を行った時点ではメモリには実態がない。

クラスでは関数もメンバにできる。これをメンバ関数という。

```Class1b.cpp
#include <iostream>

using namespace std;

class Student {
public:
  char name[10];
  int scoreJapanese;
  int scoreMath;
  int scoreEnglish;

  void Show();
};

void Student::Show() {
  cout << "名前 :" << name <<endl
       << "国語 :" << scoreJapanese << endl
       << "数学 :" << scoreMath << endl
       << "英語 :" << scoreEnglish << endl;
}
int main()
{
  Student student[] = {
    {"たなか", 12, 21, 32,},
    {"やま", 12, 42, 55,},
    {"きあ", 43, 53, 23,},
  };
  int size = sizeof student / sizeof *student;

  for(int i = 0; i < size; ++i) student[i].Show();
}
```

###06-02　メンバ関数

メンバ関数を実装するときはクラス宣言の中にプロトタイプ宣言をする。

```
クラス名::をつける
Student::Show()
```
スコープ演算子と同じと考えて大丈夫。
###06-03　コンストラクタ
前2節では、オブジェクトの初期化を構造体と同じようにしていたが、**これは絶対にやるべきではないもの**。
```Student student;```と書くだけでクラスの初期化ができる特殊メンバ関数を使う。これをコンストラクタという。

```Constr.cpp
#include <iostream>

using namespace std;

class Integer {
public:
  int m_value;
  Integer();
  void show();
};

//コンストラクタ
Integer::Integer()
{
  m_value = 0;
}

//メンバ変数表示
void Integer::show() {
  cout << m_value << endl;
}
int main(){
  Integer a;
  Integer b;
  Integer c;

  a.show();
  b.show();
  c.show();
}
```
<img width="75" alt="スクリーンショット 2019-03-10 1.21.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/13a46a0d-73bc-fdcc-482e-db9cbee2a8ba.png">
コンストラクタの戻り値の型にvoidと書いてはいけない。
こう書いておけば、クラスが呼ばれたときに自動的にコンストラクタが呼ばれ,メンバ変数m_valueが0で初期化される。

###06-04 引数つきコンストラクタ
m_valueを好きな値で初期化する方法は、コンストラクタに引数をつける。

```constr2.cpp
#include <iostream>

using namespace std;

class Integer {
public:
  int m_value;
  Integer();
  Integer(int num);
  void show();
};

//コンストラクタ
Integer::Integer()
{
  m_value = 0;
}

Integer::Integer(int num)
{
  m_value = num;
}

//メンバ変数表示
void Integer::show() {
  cout << m_value << endl;
}
int main(){
  Integer a;
  Integer b(100);
  Integer c(30);

  a.show();
  b.show();
  c.show();
}

```
クラスのメンバ初期化は必ずコンストラクタで行う。
引数なしのコンストラクタをデフォルトコンストラクタという。デフォルトコンストラクタは定義しなかったら勝手に作られる。ただし、デフォルトコンストラクタ以外のコンストラクタを作った場合はデフォルトコンストラクタは自動で作られない。自分で作る必要がある。

#終わりに
明日は6章終わらせる
おやすみなさい