khurata’s blog

khurata’s blog

初心者が C でコードを書くとき意識した方がいいこと

(もともと「Yahoo!知恵袋」の「知恵ノート」だったものを転載しています)
(最終更新日時:2017/4/18)投稿日:2017/4/16

はじめに

 下記質問について、回答を書き下していたのですが、投稿する前にベストアンサーが決定されたので、投稿できずじまいでした(悲)。

C言語で初心者がコードを書くとき意識した方がいいこととかありますか?」
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10172991805

 せっかく書いたものを捨てるのももったいないので、この場を借りて掲載します。

 

C言語で初心者がコードを書くとき意識した方がいいこと

(1)1関数1機能1名称を徹底する

 1つの関数がおおむね30行を越えるような場合は、その関数の持つ機能を見直してみる。
 1つの関数は1つの機能だけを実現するものとし、そのような名前を付ける。
 1つの関数の中に「すっきりとした単機能の名前」が付けられないような「複数の仕事」を持ち込まない。

 ただし、どう書いても長くなる処理(たとえば switch の分岐先が多い、など)の場合、行数の縛りにとらわれる必要は無い。
 30行を越えるような関数は、知らず知らずのうちに複数の機能を持ち込んでいる場合が多いので、「行数の多さ」は、「まず疑うべき関数」を見つけるためのフィルターである、というだけのことである。

(2)ちゃんとした名前を付ける

 上記(1)にも関わることだが、関数だけでなく変数や定数にも、ひと目でそれと分かる名前を付ける。 けっこう面倒だが、これは本当にやっておいた方が良い

(3)自分を疑う

 プログラムは思った通りに動くものではない。 プログラムは書いてある通りに動く。 従って、作ったプログラムが目的通りに動作しない時、その全責任は自分の側にある。 この姿勢を徹底して持ち続けること。
(場合によってはコンパイラーのバグである事もあるが、その手の問題に行き当たるのはもはや初心者ではない)

(4)const を積極的に使ってみる

 すでに n2q37 さんが書かれている通りなので割愛。

(5)翻訳単位を意識する

 ソースを分割コンパイルして、それぞれの部分を独立保守できるように作ってみる。 make を使ってそれをやってみるとなお良い。
 大規模なソースを一括コンパイルすることが悪いわけではない。 しかし、翻訳単位が分かっていないと読めないソースが多々存在するので、これを意識できるかどうかは「たくさんの教材が得られるか」に関わってくる。

(6)記憶クラスを意識する

 これは C の基本の1つだが、初学者向けの教育では触れられていないことが多々有る。 たとえ小さなプログラムであっても、記憶クラスを意識して設計できるようになれば、初心者を脱しつつあると言ってもよい。

(7)実行コストを意識する

 自作のプログラムが、実行時にどれだけのバイト数のメモリーを必要とし、どれくらいの時間オーダーで実行完了するのか、を意識するように心がける。
 C が誕生した頃と違って、今時はメモリー量を気にするようなプログラミングがされることはほとんど無いが、C はそれを明瞭に意識できる数少ない高級言語であり、この感覚を持つことは後々役に立つだろう。

(8)何が C で、何が C でないかを意識する

 C 関連の質問で本当に多いのが、「C は何でもできると聞いたが、黒い画面に白い文字ばっかりで…」という疑問である。
 C という言語それ自体が出来ることは少ない。 C にはいわば「頭脳」しかない。 C はメモリーの内容を書き換えたり、数値計算をしたりする事は出来る。 しかしキーボードやファイルからデータを受け取ったり、文字を表示したり、画像を扱ったり、通信したり、などの事は C だけでは全くできない
 C が万能と言われるのは、豊富なライブラリーという「身体・手足」を「頭脳」につなげるからである。

 また、Visual StudioXcode のような開発環境を使っている初心者は、目の前のエラー・メッセージが「C プログラムに関わるものか」「開発環境に関わるものか」を区別できずに悩む。 今時の開発環境は、とても多機能で、初学者の手に負えるものではない。
 ゆくゆくはそれを使いこなすのだとしても、最初のうちに複雑さを避けるためには、最初はなるべくシンプルな開発環境で学び始める方が良い。 たとえば LinuxMac OS X の「端末」や、「Visual Studio コマンドプロンプト」を使うと良いであろう。

(9)有名なアルゴリズムはひと通り試してみる

 たとえばソーティングについてだけでも「バブルソート」「単純選択ソート」「単純挿入ソート」「シェルソート」「ヒープソート」「クイックソート」「ラディックスソート」「自然併合ソート」などの有名なアルゴリズムがある。
 これらを時間のあるときにひとつずつ自作する、という経験を積むことは有用である。
 プログラムを作るにあたっては、適切なアルゴリズムを知っているかどうかが成否を分けることがよく有るからである。

(10)下記の「知恵ノート」を読む

 手前味噌で恐縮だが、「知恵袋」を利用したり、他人に質問する場合は、下記「知恵ノート」の内容を思い起こすと良い。

「★★★回答を寄せ付けない質問の仕方★★★」
https://khurata.hatenablog.com/entry/2019/04/04/072441

 

プログラミングの時上級者の方はどんなことを意識している

 何をもって上級者と言うかは諸説ありましょう。 私自身が上級者と言えるかどうかは怪しいですが、自分の事を言えば次のようなことが挙げられます。

(1)自分でプログラムを書かない

 凡人が考え付くような大抵の処理は、すでに誰かが作っている。 ほとんどの場合、自分がゼロから書き上げたプログラムよりも、偉大な先人が書き残し、時の試練を経たコードの方が優れているであろう。
 従って、「これはどこかにありそうだな」と思ったら、そのプログラムを書くのではなく、探すことに重点を置く。

(2)テストは小さい単位から積み上げる

 プログラムをひと通り作り終えてからテストするのではなく、小さい「部品」の段階でテストを済ませておく。 つまりプログラム全体が「正しい部品」だけから成り立つようにする。 C の場合は「1機能関数」を徹底的にテストするのである。

(3)行き詰まったら時間を置く

 どうにもうまくいかない時、というのはままある。 そんな時、まずは寝食を忘れて考え込むが、数日悩んでも解決が見いだせない時は、その問題をひとまず放置して他のことに取り組む。
 時間が経ってからあらためて見てみると、意外と解決策が浮かび上がってくることが多い。

(4)原理主義にとらわれない

 たとえば「goto は使うな」と初学者は教わる事が多いであろう。 しかし goto も場合によっては使いどころがある。
 「べからず集」やイディオムは確かに有意義なのだが、常に絶対に妥当なものではない

(5)コメントにコードの説明を書かない

 ソースにコメントを書くべきか・書くなら何を書くべきか、については長年の論争がある。 私自身は「コメントは必要ならば書くべきだが最小限に」「書く場合はコードの説明ではなく何をしたいかを書く」が妥当である、と今のところは信じている。

 基本的には、コメントが不要なコードが書ければ、それに越したことはない。 コードこそが唯一の実装仕様であるからだ。 関数名や変数名が妥当であれば、プログラムはまるで説明書のように読み下せるはずである。
 とは言え、全てをそのようにするのはしんどい。 だから、コメントを補助的に使うことは許されてよいと私は思う。
 ただし、それがコードの説明、すなわち実装仕様の記述になってしまっては意味が無い。 そこには要求仕様寄りの事を書くべきだと私は思っている。

 

あの時こんなことを意識しておけばよかった

(1)ポインタ(の文法)

 恥ずかしながら自分が C のポインタ(に関わる諸文法)を「自分のモノにした」と感じたのは、C を使い始めて相当の年数が経ってからだった。 それまでは他人の作ったプログラムを見て、それらを真似てポインタを使うプログラムを書いており、またそうした経験則をたくさん積んだので、それらは結果的に正しく動いてもいた。
 しかし今となっては「先にきちんと分かっておいた方が、はるかにラクにプログラミングできた」と後悔している。
 下記の「知恵ノート」は、この個人的な後悔から生まれた。

「配列と文字列とポインタ」
https://khurata.hatenablog.com/entry/2019/04/04/063814

(2)カンマ演算子(順序演算子

 これについて積極的に触れられているテクストや、実際の使用例があまり見つけられなかったので、長年、これを意識する事が無かったが、使ってみると大変便利である。
 初心者を脱した頃の人は、よく3項演算子を使いたがるし、かつては私もそうだったが、今となってはカンマ演算子の方に「ありがたみ」を感じる。 なぜもっと早いうちに使おうとしなかったのかが悔やまれる。

 

おわりに

 あまり晒したくない恥ずかしい内容も含まれていますが、初学者の方々にとって、何らかのご参考になれば幸いです。
(転載以上)