手を動かしてプログラミングをする意味【新人向け】 

## はじめに
こんにちは。

僕はこの4月で社会人生活3年目を迎えます。大学はがっつりプログラミング系の専攻を学んでまして、卒業後エンジニアの仕事をしています。僕の今までのQiitaの記事はJavaScript関連の記事が中心に書かせていただいたのですが、今回の記事ではいつもの記事と全然違う記事を書いていこうかなと思います。

今回の記事は**「プログラミング」ってどうやって勉強するんだろう？**ということを自分なりにまとめてみました。実際自分自身も大学入学するまで「プログラミング」というものをまったく知らなかったし、どんな勉強すればいいねん？と嘆いていたので、もし同じ境遇の方々がいたら、役に立ててもらえると幸いです。


※軽めの自己紹介
プログラミング7年目（底辺）
フロントエンド系のエンジニアをしています。
仕事はほぼJavaScriptしかいじっていませんので、JavaScript関連には慣れてきましたが「日々勉強は怠らず」をモットーに頑張っています。ほかの技術(Golang,AWS)も勉強中です。

## この記事の対象
- 4月から社会人として「**新人エンジニア**」になる人（特に大学であまりプログラミングをやっていなかった人）
- **未経験からエンジニアになりたい**人
- 大学（高校）からプログラミングを学ぶ人


要はこの記事の対象は、

- 「**全然プログラミングとかやってこなかったけど来月からエンジニアだ...やばい...**」って思う人
- 「**プログラミングに興味あるけどどうやって勉強しようかな...？**」って思う人
- 「**これからプログラミングを学ぶんだ！頑張ろう！**」って思う人

を対象にしています。

## 今までプログラミングは「覚える」ものだと思っていた
大学や会社の研修の中でプログラミング系の教科書や参考書を買ったりすると思います。僕に関していうと、大学では最初にC言語を勉強することになったので、参考書として最初に買ったのは「**苦しんで覚えるC言語**」という参考書を買いました。この参考書を買った理由は単純に名前で選びました。「どうせプログラミングなんて苦しむものだろ！買っちゃえ！」っていう心情からこの本を買ったんですが、この本の内容を丸暗記しようとしたことが間違いの始まりですね。

[参考：苦しんで覚えるC言語](https://www.amazon.co.jp/%E8%8B%A6%E3%81%97%E3%82%93%E3%81%A7%E8%A6%9A%E3%81%88%E3%82%8BC%E8%A8%80%E8%AA%9E-MMGames/dp/4798030147)

### プログラミングの暗記は多分意味がない
この本の内容を覚えたら、大学のどんな課題も楽勝だぜ！って思って暗記を始めましたが、結論から申し上げると楽勝どころか、課題に負ける方が圧倒的に多かったです。（今考えるとなにやってるんだ...と思います...）

「**え、この問題、【進〇ゼミ】でやった問題だ！！！！！！！この問題もらったぜ！！！！！**」とは残念ながらなりません。参考書でててくる問題がそのまま大学の課題や定期試験で出ることなどまずないです（あったら奇跡だと思った方がいいです）。部分的に似ている問題はでてくるかもしれませんが。たとえば、大学の先生が「この問題、一語一句そのまま変えずテストに出すぞ！」と言ったなら、それは暗記したほうがいいかもしれません。

僕が重要だと思うのは参考書で出てくる**用語・文法・問題**をどのような形で勉強するかかが大事だと思っています。この捉え方によって、いろんなプログラムを書く効率性や柔軟性が変わってくると考えています。ここでいう「用語・文法・問題」は下の箇条書きでまとめています。

- **用語**
    - プログラミング業界（IT業界）で出てくる言葉
        - 例：コンパイラ、メモリ、OS、ネットワーク
- **文法**
    - プログラミングをする上でのルール事項
        - 例：変数宣言時はC言語では〇〇で、JavaScriptでは□□だよ～。
- **問題**
    - 参考書等で出てくるサンプル問題（とその解答例）
        - 例：次の〇〇をC言語で実装せよ。

まずは参考書で**押さえておくべき用語や文法**は覚えましょう。特に文法に関して言うならば、これから何回も出てくるフレーズ等(例：条件文、関数、継承)があるので押さえておきましょう。参考書で出てくる**問題**はそのまま覚えるのではなく、流れをつかんだうえで勉強しましょう。

例えば以下の問題があるとします。

> ２つの整数の大きい方を選ぶ関数を作成しなさい。２つの int 型引数を取り、大きい方の数値を戻り値として返すこと。

簡単な問題を選びましたが、「**この問題が来たらこのコードだ！**」って言って参考書の回答のプログラムを読んでそのまま貼り付けて「**はいはい、わかりましたー**」はもちろんだめです。問題の流れをとらえましょう。

### 問題の流れを紙に書く(視覚化する)
僕は、最初はよく紙で問題の流れを視覚化して、自分がちゃんと問題が理解できるレベルまで問題をかみ砕いて、そのあとにPCでプログラムを書いていました(iPadのメモ機能＋ペンでも可)。
この視覚化した図は、人に説明するときにすごく便利になります。「こういう機能を実装するので、こんなプログラムを書きました」って口では言えるんですが、聞いた相手が具体的なイメージをもっているかはわかりません。そのイメージをより分かりやすくするために流れを視覚化してしましょう。

この問題でいうと以下の通りです。
> 問題２つの整数の大きい方を選ぶ関数を作成しなさい。２つの int 型引数を取り、大きい方の数値を戻り値として返すこと。

＝＝＝＝＝**考え方**＝＝＝＝＝
1. 「２つの整数」→　int型を定義する（この整数の範囲ってどうなのかな～？負の数も扱っていいのかな～？）。
2. 「大きい方を選ぶ」→　比較（この２つの整数に対して**if文**だね～。）
3. 「関数を作成しなさい」→　関数を作る(function(){}みたいな形だね～。)
4. 「大きい方の数値を戻り値として返すこと」→return文を使う。戻り値は整数。(int 関数名(引数){return}みたいな形だね～～)
＝＝＝＝＝＝＝＝＝＝＝＝＝
という感じで問題を細分化していきます。問題文をかみ砕いていくと文法単位で扱えるようになります。ここで初めて「進〇ゼミでやった問題だ！！（問題というよりも見たことあるフレーズじゃん！！）」って感覚が生まれます。ちなみに先ほどの問題の解答例は以下です。

```c
//大きい数値を返す関数を定義
int MaxValueChoice(int num1,int num2){
    if(num1 > num2){//比較
        return num1 //戻り値
    }else{
        return num2
    }
}
```
プログラミングは暗記というよりも、プログラミングで何を実装したいかのイメージを細分化して、その細かい部分（要素）を1つ1つ作り、それを重ねることでプログラミングが上達するのでないかなと思います。文法とかも忘れちゃってもGoogle先生で検索して引っ張り出すこともできるので安心してください。しかし、ただイメージするだけではなく、先ほどの「プログラミングを視覚化する」といったような行程同様に「**手を動かしてプログラミングをすること**」も大事になってきます。

※プログラミングの考え方等は「**リーダブルコード**」にまとめられていて、読みやすくわかりやすいです。
[リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック](https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3NIY09NFGP9EB&keywords=%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89&qid=1553664935&s=books&sprefix=%E3%82%8A%E3%83%BC%E3%81%A0%E3%81%B6%2Cstripbooks%2C248&sr=1-1)

## 手を動かしてプログラミング（アウトプット）するだけで全然違う
手を動かして、プログラミングを勉強するだけで全然違います。またその自分が作ったプログラムを誰かに説明することも大事だと考えています。例えばチームでプログラムを作っていると必ずと言っていいほど、誰かから聞かれます。

「**このコードの意図を教えて**」

ここで「仕様書にそうやって書いていましたー」と言いたくなります。きっと我々が書いているプログラムは当たり前ですけど、1行1行ちゃんと意味があります。たかが1行改行したことでも変数を宣言することでも意味はちゃんとあります。チームでプログラムを作るうえで上司等に説明をする機会があると思いますが、**自分ひとりでプログラミングの勉強をする中でも、自分が作ったプログラム1行1行をちゃんと説明できるよう**に心がけましょう。そしてその訓練を積み重ねていってください。

また**実行結果**も確認しましょう。実行結果はうまくいけば自分が意図した結果が出てくるとは思いますが、うまくいかないとエラーが吐かれます。「**なんやねん！このエラー！やめた！**」って言って逃げたくなる気持ちもわかります。ただ逃げるのではなく、Googleで調べたり人に聞くことで**エラーを解決することもプログラミングの一工程**です。プログラミングはうまくいかないこと（自分が実装したいことがうまく表現できないこと）の方が多いです。最初は地道にプログラムの1行1行とにらめっこして、「こうでもない、ああでもない」と言いながら1日が過ぎるかもしれません。でもプログラミングってそういうものです。「最初は」と言いましたが、僕は今でも意味わからないエラーが出てきて、Googleに助けてもらっている日々です。**プログラミングはプログラムを書いて、エラーが出て、調べて、修正して、またエラーが出て、、、（以下ループ）といったような形で日々学んでいくものだと思います。**プログラムを書くという作業を起点にいろいろ成長すると思うので、ぜひ手を動かしてプログラミングしていきましょう！

逆を言うと本を読んで、プログラミングが理解したという感情は捨てましょう。正確にいうならば「**プログラミングの土台ができていない上で、本を眺めてコードを理解する**」のはやめましょう。プログラミング文法が理解でき、プログラミング等のアウトプットの練習をそれなりにしているのであれば、復習がてらにコードを眺めるのはいいことだと思います。どの学問でもそうですが基本という土台が崩れると誤った解釈がおこるかもしれません。プログラミングの土台というのは明確に定まったものではありませんが、例として、文法の基礎基本を繰り返して、自分で考えたプログラムが数千行程度書いて、実行結果がうまくいったら、土台ができているとみなしてもいいかもしれません。

このように、地道な訓練の中を通じて、プログラミングの文法を学び、色々考えながら自分のプログラムを作り、エラーと戦い、そのプログラムを実行することで自分のプログラミングとしての土台ができると思います。

## まとめ
プログラミングは難しいです。しかし、プログラミングに対して「楽しい」という感情が少しでも現れると、それは1歩成長したことだと思います。プログラミングは1週間で完璧になるようなものではないし、そもそも完璧になれません。なので、地道に進むしかないです。地道に頑張るしかないと思います。

あとはプログラミングのモチベーションを保つために、自分がやっていることは達成感を積み重ねることです。例えば毎日1個だけでもいいので、できた（理解した）ことをメモしましょう。今日はこういう関数を作った、また別の日にはその関数にこういう機能を加えた、またまた別の日はポインタについてのプログラムを書いた、とかとか。プログラミングのモチベーションの保ち方は人それぞれかもしれませんが、なににせよ続けることが大事だと思います。

今回のこの記事は50％自分のために書いた感じもあります。最近Qiitaのトレンド等で書いてある記事やプログラムを見て、「ああ～～すごいなあ～～いつかこうなりたいなあ～～」って思っただけで、結局寝るといったことが多かったので、初心に戻って「手を動かしてプログラムを書く」ことを忘れずに頑張ろうかなと思って書きました。また、4月から社会人スタートだったりといろんな挑戦が始まると思いますが、あきらめず頑張ってください！