この記事は、組込みエンジニアを目指してC言語を学び始める人のための練習問題シリーズ(全8テーマ)の目次となる記事です。

分厚い入門書を1冊やりきる必要はありません。組込みの入口で実際に書くC言語は、変数・if・ループ・配列・関数・ポインタ・構造体・ビット演算の8テーマにほぼ収まります。このシリーズは、その8テーマだけを講義形式の解説と自作の練習問題・回答例で身につける形にまとめました。

<自己紹介>
筆者は現役の車載組込みソフトエンジニアです。機械系出身でゼロ知識からこの世界に入り、自分がC言語(特にポインタ)でつまずいた経験をもとに、「組込みで結局使うのに、習っていないから詰まる」要素だけを必須として選びました。このシリーズで最低限の言語知識を理解し、最終的にArduinoでマイコンプログラムを自作できるようになるのをゴールにしています。

この8テーマを終えると、何が書けるようになるか

8テーマを終えた読者には、C言語 総合実力テストを用意しています。エアコンのリモコンを模したプログラムを、要件定義書と設計書だけを渡されて実装する内容です。マイコンもリモコンの実物も使わず、ボタン番号をキーボードで入力して画面に状態を表示する、素のCプログラムです。

具体的には、こういうコードを自分で書くことになります。

総合実力テストで実際に書くもの

  • 停止・起動・冷房・暖房・風量の5つの状態を行き来する(if / switch
  • ボタン番号を読み取り、数字が入るまで聞き直す(ループ・do-while
  • 温度を変えた履歴を3件ぶん残し、いっぱいなら古い方から捨てる(2次元配列
  • 温度・風量・状態・履歴を1つの構造体にまとめ、各関数へ渡して書き換える(構造体・ポインタ
  • 電源・モード・風量・警告を1バイトのステータスレジスタに詰める(ビット演算

そしてその次が、Arduino 基礎ドリルです。総合実力テストで紙の上に書いたエアコンのプログラムを、温湿度センサと赤外線LEDを使って実際に動く形にします。画面に printf で出していた値が、そのまま本物のセンサの値に変わります。

つまりこのシリーズは、「文法を覚える」で終わらせず、「マイコンを動かすコードが読み書きできる」まで一続きにするための最初の8テーマです。

なぜ「8テーマだけ」でいいのか

C言語の入門書は、たいてい数百ページあります。ですが、そのうち組込みの入口で必要になるのは一部です。

これは感覚ではなく、数えて確かめられます。当ブログのArduino 基礎ドリル(全7テーマ+総合課題)に載せているコードを集計すると、次のようになりました。

C言語の要素 Arduinoドリル9本での使用
ビット演算(&= |= ^= << >> 74回/9本中8本に登場
関数の定義 77回/9本中8本に登場
動的メモリ確保(malloc / free 0回
ファイル入出力(fopen など) 0回
文字列操作の関数(strcpy strcmp など) 0回
関数ポインタ 0回

入門書の後半に出てくる動的メモリ確保・ファイル入出力・文字列操作の関数は、マイコンを動かすところまでで一度も出てきませんでした。逆にビット演算と関数は、ほぼ全部の記事に出てきます。

もちろん、これらが一生不要という話ではありません。仕事で扱う範囲が広がれば必要になります。ここで言いたいのは「入口では要らない」ということです。最初に全部やろうとして途中で止まるより、8テーマを終えてマイコンを動かしてしまったほうが早いです。

もう一つ、私自身の経験も根拠にしています。未経験で組込みの会社を受けたとき、就職試験で問われたのはこの8テーマの範囲でした。逆に言えば、ここを飛ばすと、マイコンの学習記事を読んだときに「習っていない文法がいきなり出てくる」状態になります

全8テーマと、進む順番

ここからが本編の入口です。8テーマの中身と、進む順番をまとめます。

まず、どんなプログラムでも使う基本の5テーマです。

# テーマ 学べることと、総合実力テストでの役割 記事
1 変数・型・演算子 型と入る値の範囲、定数、四則・比較・論理、printf。総合では温度の範囲チェックと、状態を表す #define 定数に使う。===の取り違えは鉄板バグ 記事を読む
2 if / else 条件分岐 if・else if・switch・三項演算子。総合では5つの状態を行き来する分岐(switch)と、温度が上限・下限に届いたときの表示の出し分けを担う 記事を読む
3 for / while ループ 繰り返し、do-while、break / continue、前置と後置。総合ではプログラム全体を回し続ける while と、正しい値が入るまで聞き直す do-while になる 記事を読む
4 配列 宣言・添字・走査・2次元配列。総合では温度変更の履歴(2次元配列)と、状態名・風量名の対応表に使う 記事を読む
5 関数 定義・引数・戻り値・プロトタイプ宣言・スコープ。総合では、状態ごとの処理を関数に分け、次にどの状態へ行くかを戻り値で返す設計を担う 記事を読む

次が、組込みでとくに出番の多い3テーマです。ここがWebやアプリのC言語学習ではあまり強調されない部分で、マイコンを触ると毎日のように使います。

# テーマ 学べることと、総合実力テストでの役割 記事
6 ポインタ(最小限) &*、なぜ必要か。総合では、各関数へ構造体を渡して呼び出し元の値を書き換えるのに必要になる。実機ではレジスタを直接読み書きするときに使う 記事を読む
7 構造体(最小限) 複数のデータを1つに束ねる、typedef。総合では温度・風量・状態・履歴を1つの構造体にまとめる 記事を読む
8 ビット演算 & | ^ ~ << >>、マスク・シフト。総合では電源・モード・風量・警告を1バイトのステータスレジスタに合成する。実機ではピンとレジスタの操作そのもの 記事を読む

迷ったら1から8へ順番に

迷ったら、1から8まで順番に進めてください。後ろのテーマは前のテーマの内容をそのまま使うので、順番に積み上げるのが最短です。

  1. #1 変数で、値を入れる・比べる・表示するを覚える
  2. #2 ifで、条件によって動きを分ける
  3. #3 ループで、同じ処理を繰り返す。ここまでで「動くプログラム」の形になる
  4. #4 配列で、値をまとめて持つ。#3のループと必ずセットで使う
  5. #5 関数で、長くなったコードを部品に分ける
  6. #6 ポインタは最大の山場。#5の関数に「書き換えてほしい値」を渡すところでつながる
  7. #7 構造体#8 ビット演算で、組込みらしいデータの持ち方を覚える
  8. 総合実力テストで、8テーマを1本のプログラムに組み上げる

1〜5まで進めば、マイコンの入門記事(Lチカなど)は8割がた読めるようになります。かかる時間の目安は1テーマあたり30分〜1時間、全8テーマで10時間前後です。

各記事の進め方

C言語は、数あるプログラミング言語の中でも特に細かくルールが決まっています。いざ自分でコードを書くと、変数の宣言のしかたやfor文の書き方が思い出せず、手が止まることが多々あります。これは知識が「読む」止まりで、「書ける」に変わっていないからです。

そこでこのシリーズは、各テーマを講義形式の解説+練習問題7問と回答例で進める形にしました。読むだけで終わらせず、実際に手を動かしてください。

  • 上から順に解く(後のテーマは前のテーマで学習した内容を使うため)
  • まず自分で書いてみて、回答例と照らし合わせる(回答は各問題の「+」で開きます)
  • 各記事の「例:実務で実際に書くコード」で、その文法が実際の開発のどこで使われるかを確認する

次のテーマへ進んでよいかの目安は、各記事の冒頭にある「このテーマの要点」を、見ないで自分の言葉で言えるかどうかです。言えなければ、練習問題をもう一度解いてから進んでください。

また、各記事の末尾には「1週間後に、もう一度ここへ戻る」という節を置いています。解いた直後は誰でも解けるので、間をおいてから解き直したときに手が動くかで確認してください。

本記事の読者対象は「C言語はほぼ初めて」「組込みやマイコンの学習を始める前に基礎を最低限得たい」人です。なぜ組込みでそもそもC言語なのかが気になる人は、先に組込みでC言語が使われる理由を読んでおくと、学ぶ意味がはっきりします。

始める前に決めること|コードを動かす場所

学習前に一つだけ。C言語は、テキストで書いただけでは動かないので、コンパイル、実行という手順が必要です。「コンパイル」とは、人間が書いたC言語のコードを、コンピューターが実行できる形に翻訳する作業のことです。プログラムは「書く → コンパイルする → 実行する」の順で動きます。とはいえ身構えなくて大丈夫で、下で紹介する環境なら「実行」を押すだけで、裏でコンパイルまで自動でやってくれます。

問題を解き始める前に、書いたコードを実際に動かす場所を決めておきましょう。ここでつまずくと練習に進めません。だから最初は「インストール不要」で始めるのがおすすめです。目的別に2つ挙げます。

タイプ 使うもの こんな人に
①今すぐ始めたい オンライン実行環境(paiza.IO など) まず手を動かしたい人。インストール不要で、ブラウザだけでCを書いて実行できる
②ローカル環境で実行したい VS Code + gcc(Windowsは MSYS2 で導入) 手元でいろいろ試したい人。VS Codeでコードを書きたい人

迷ったら①でOKです。paiza.IOなら、サイトを開いて言語で「C」を選び、コードを書いて実行ボタンを押すだけ。環境構築で消耗せず、すぐに1問目へ取りかかれます。数をこなして「ちゃんとした環境が欲しい」と感じてから、②のローカル環境(VS Code+gcc)へ移れば十分です。gccのインストールは初心者がつまずきやすいので、基礎をつかんでからで構いません。

VS Codeのターミナルにprintfの実行結果「合計 = 360 円」が表示されている画面
筆者の環境(VS Code+gcc)での実行例。printf の結果がこのようにターミナルへ表示される

なお、このドリルの問題はすべて、結果を printf で画面に出す素のC言語で解きます。マイコン実機ではプログラムの入口や表示のしかたが少し変わりますが、変数・if・ループ・関数といった文法そのものはまったく同じです。まず①か②で文法を固めて、そのあとにArduino 基礎ドリルで実機へ進みます。

未経験がつまずく2大ポイント

8テーマの中でも、未経験者がとくにつまずきやすいポイントが2つあります。先に知っておくと、そこへ来たときに慌てずに済みます。

①「=」と「==」の取り違え

C言語では、=(代入)と==(等しいか比較)はまったくの別物です。ところが見た目が似ているため、if (x = 5) のように書いてしまう間違いが定番です。これはエラーにならずに動いてしまうことがあるので、原因に気づきにくい厄介なバグになります。テーマ1で、ここを最初に固めます。

②ポインタの壁

もう一つの山場がポインタ(テーマ6)です。多くの人が入門書のポインタの章で手が止まります。ただ、組込みではポインタを避けて通れません。レジスタ操作も、関数にデータを渡す場面も、ポインタを使うからです。

<一言メモ>
ポインタを理解するにはメモリを理解する必要があるのですが、これが最もつまずきやすいポイントになるかと思います。
そのため、ポインタ関連の記事はとくに手厚く、初学者でも理解しやすい記事を作成していますのでご安心ください。

コツは、頭の中だけで考えないことです。&x をそのまま printf で表示させると、変数の住所が数字として見えます。目で見える形にしてしまえば、ポインタはただの「住所を入れる変数」です。ポインタがなぜ組込みでそこまで重要なのかは、テーマ6のポインタが組込み開発で重要になる理由で、練習問題とあわせて掘り下げます。

さらに演習したい人へ(参考)

本シリーズの問題は、組込み向けにすべて自作したものです。「もっと数をこなしたい」「大学の演習レベルで腕試ししたい」という人は、外部の問題集にあたるのも良い方法です。

たとえば京都産業大学が公開している基礎プログラミング演習I「100本ノック」は、C言語の基礎を段階的に練習できる問題集です。難易度が順に上がる形なので、腕試しに向いています。なお、本シリーズはこの問題を転載・流用していません。

よくある質問(FAQ)

どのテーマから始めればいい?

テーマ1の「変数・型・演算子」からで大丈夫です。後のテーマは前のテーマを使うので、番号順に進めるのが一番スムーズです。完全な初心者ほど、順番を飛ばさないことをおすすめします。

8テーマ全部やらないとダメ?

組込みの学習を快適に進めたいなら、8テーマすべてが必須です。どれも実際のコードで登場するため、飛ばすと「習っていない文法が出てきて詰まる」ことになります。まずは1〜5だけでも、マイコンの入門記事はかなり読めるようになります。

Arduinoに進むには、8テーマ全部終わっている必要がある?

全部終えてからのほうがスムーズですが、必須ではありません。Arduino 基礎ドリルの側では、変数・if・ループ・関数・ポインタ・ビット演算の6つを確認してから始めることをすすめています。配列(テーマ4)と構造体(テーマ7)は、Arduinoを進めながらでも間に合います。なかでもビット演算はArduinoドリル9本のうち8本に出てくるので、ここだけは先に済ませてください。

問題はどこかの転載?

いいえ。本シリーズの問題はすべて、筆者が組込み向けに自作したものです。外部サイトの問題を転載・流用していません。さらに数をこなしたい人向けに、参考として外部の問題集を紹介しています。

まとめ|8テーマだけ手を動かせばいい

最後に要点を整理します。

  • 組込みの入口で必要なC言語は、8テーマ(変数・if・ループ・配列・関数・ポインタ・構造体・ビット演算)で足りる
  • 1〜5がどんなプログラムでも使う基本、6〜8が組込みで出番の多い3つ
  • 入門書の後半にある動的メモリ確保・ファイル入出力・文字列関数は、マイコンを動かすところまででは一度も出てこない
  • つまずきやすいのは「=と==」「ポインタ」の2か所
  • 読むだけにせず、各テーマの練習問題で「書ける」状態にするのが近道

分厚い入門書を1冊やりきる必要はありません。この8テーマだけ手を動かせば、組込みの学習でC言語に足を引っぱられなくなります。まずはテーマ1の変数・型・演算子から始めてみてください。

次に読む