google-site-verification: google3bd66dd162ef54c7.html
FC2ブログ

Arduino よもやま話 -1 (関数を書く順序)

1.まえがき
 これまでArduinoを使っていろいろな物を作ってきましたが、そういう経験を通じて得られた知識やノウハウなどを整理すると、これからArduinoを勉強しようという方の参考になりそうです。まあ、そんなたいそうな話では無くても、自分の経験を整理することで、新たな発見(勘違いの発見?)があるかも知れません。

 そんなことで、「Arduino よもやま話」と題して、感じたことや気付いたことを記事にしてみることにしました。ベテランの方から見るとアホみたいなことばかり書くかもしれませんが、ご容赦下さい。なお、Arduinoではプログラムのことをスケッチと言いますが、ここでは原則としてプログラムと呼ぶことにします。

2.関数を書く順序の問題
 初回の記事は「関数を書く順序」です。ArduinoはC言語をベースに、初心者向きに使い易くしたもの、という理解で良いと思いますが、ちょっと違いがあります。そのあたりが一番はっきりと出ているのが、関数を書く順序だと思います。

 Arduinoのプログラムを触った人なら誰でも知っていますが、Arduino のプログラムは以下のような構造になっていて、setup() とloop() をプログラムの最初に書くことになっています。
void setup() {
}
void loop() {
}
 いつもこういう書き方になっていたら判り易いだろう、ということでこの書き方、つまり先頭にsetup()を置いて、次にloop() を書くことになっています。簡単なプログラムなら、この構造の中に全部の内容を書くことが出来ますが、少し複雑な処理を書く場合は、サブルーチンを使う、つまり関数を使って下記のように書くことになります。
void setup() {
}
void loop() {
hogeFunction();
}
void hogeFunction(){
}
 hogeFunction() が追加された関数です。

 Arduinoで関数を使う場合、上に書いたようにように、loop() の後に書くしかありません。何しろsetup() と loop() は先頭に書くのが約束なので、これより前にhogeFunction() を書くわけにはいかないからです。

 これ、Arduinoでは当たり前の書き方ですが、C言語でこの書き方は許されません。関数は、それが実行される前に定義しておく、(あるいはプロトタイプ宣言を行って入出力を明確化しておく、)というルールなので、このままでは、Cコンパイラは通りません。

3.解決策
 どうしているかと言うと、コンパイラに掛ける前にプリプロセッサで構文解析を行い、抜けているプロトタイプ宣言を追加しています。
 プリプロセッサでは setup とloop の処理を、main()の中に展開している、という解説がよく出てきますが、同時にプロトタイプ宣言の追加ということもやっています。

 コンパイラの前処理でこういう操作が行われているため、ユーザーは関数の定義の順序を気にしないでプログラムを書くことが出来るようになっています。

Arduinoの関数のリファレンスに、「関数はloop()の前でも後でも、どちらに書いても良い」とさらっと書いてありますが、このために裏では面倒な処理が行われている訳です。原文だと、下記がそれに相当する部分です。
 Arduinoのレファレンスの関数の説明(Functions)に、Our function needs to be declared outside any other function, so "myMultiplyFunction()" can go either above or below the "loop()" function.

4.まとめ
 ネットにはいろいろなArduinoのプログラムが公開されていますが、その中にはsetup() とloop() が最初に書かれていないものがたまにあります。Arduinoのルール違反と言えなくも無いですが、そういう書き方される方は、たぶんC言語に精通された方なんだろうと思います。変な癖が付くと困るので、あえてCの標準スタイルでプログラムを書かれているのでしょう。
 実は昔、そういうプログラムを見た時に、なんでこういう読みにくい書き方になっているのか、理由が判りませんでした。でも、Cのプログラムとしては、そういう書き方が正しいわけです。実際、そういう書き方になっているプログラムは、高度な内容のものが多いです。

 実は私、C言語は大昔に使ったことがあって、関数の定義を先に書くなんて当たり前にやっていたはずです。でも、うん十年ぶりにArduinoからC言語を使うと、そんなことはすっかり忘れていました。後付けされた関数の参照の解決なんて、機械で出来るんだから人間にやらせるなよ、と言いたくなりますが、C言語はそういう緊張感の下でコードを書くものなんでしょう。

 ということで、よもやま話の初回は、関数を書く順序の話でした。なお、この話は "Arduino プロトタイプ宣言" あたりで検索するともっと質の良い解説が出てくると思います。
関連記事

コメントの投稿

管理者にだけ表示を許可する

大事なこと

新コーナー?興味深いです。
こうゆうことって、聞き難いんですよね、ありがたいです。
私は、Cは苦手ですが、Cからアルゴリズムを読み解く事は、結構得意です。
出来ればこのシリーズ最後の方でいいので外部関数とのリンクのやり方とかお話いただければと思います。

re:大事なこと

老技師さん今晩は。

まあこんな見方もありますよ、と言う感じでいくつか記事を書いてみたいと思ってます。

ところで外部関数と言うと、いろいろな意味がありますが、extern 宣言付きの関数でしょうか。これ難しくて私の手に負えないです。

No title

まあ苦手なことは結構です。
あまりやりすぎると、行儀が悪くなりますしね。
ただPORTのアクセス辺りを直で、
ArduinoはPORTはBit単位アクセスなので、そう思っただけです。
スケッチはAVR GCC準拠だそうでPORTDやPORTBに直接書けるようですね、ただArduinoで使用するBitを書き換えると大変だから気を付けてとありました。

老技師さんおはようございます

ちょうど、CPUのI/Oレジスタ領域を全部ダンプするプログラムを作ると面白いかな。
でもちょっと行儀が悪いかも、と思ってたところです。
カレンダー
10 | 2018/11 | 12
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード