(adsbygoogle = window.adsbygoogle || []).push({}); © 超初心者向けプログラミング入門, 超初心者向けプログラミング入門, ファイル名変更、移動、削除、存在確認, ディレクトリ作成、削除、存在確認. You (and everyone else so far) omitted the third alternative: Ignoring issues about the choice of name, then: So, in most contexts, prefer the 'enum' over the alternatives. C言語 for文、while文で無限ループを作るときは、3つのことを念頭に置いて作ろう. © Copyright 2020 C言語の組み込みプログラミングを3ヶ月でマスターし、組み込みマイコンのプログラマーを目指すためのブログ. そのため、定義後はグローバル変数のようにずっと存在し続けます。 定数って使ってますか? C言語で定数というと「#define」を使って定義するイメージが強いですよね。でも、const修飾子を使うとひとつの関数内のみで定数を扱う場合などに便利です。 この記事では、constについて constとは constの使い方 constを使う上での注意点について If you need to pass a pointer around, you must use (1). (2) can change code that you didn't want changed because it is used by the preprocessor; both (1) and (3) will not have unexpected side-effects like that. const、#defineとの違い. 整数に名前を付ける方法としては、const定数と#defineによる方法もあります。 これらを用いてもマジックナンバーの解消は可能です。 C言語では、これらを使用する場合と列挙体を使用する場合とではそれほど大きな違いはありません。 列挙型変数が定義できる. C言語の組み込みプログラミングを3ヶ月でマスターし、組み込みマイコンのプログラマーを目指すためのブログ, 組み込みマイコンのプログラムでは、入出力の処理を行うのが肝になるため、この入出力の名前をつけるのに列挙型を使用します。, 例えば、犬や猫などの動物に対して、dogは0、catは1というふうに割り当てたいときに、列挙型を用いると便利です。, 組み込みマイコンでは、エレベータで例を挙げると、入力や出力、走行フェーズやドアの動作フェーズなどに対して、列挙型をしようしています。, 構造体ではenumのところがstructとなり、列挙子の部分がメンバ変数宣言になります。, タグ名はなくても構いません。列挙子は何も指定しなければ、0から順番に割り当てられます。, 停止中、起動準備、走行中、減速中という感じですね。実際にはいろんな制御があるため、もっと複雑です。, 減速中のあとは、停止中に戻るので、この4つで、エレベータの走行の状態を表すことができます。, それらを用いて、いろんな状態監視をしています。ここでは、そのお話はしないことにします。, 列挙型に話を戻しますが、stop は 0、start は 1、run は 2、dclr は 3 ということになります。, 列挙型は、列挙子に何も指定しなければ、0から順番に割り当てられるとお話ししました。, startを10に割り付けました。何も指定しないときは、1になりますが、このように10にすることができます。, そして、start を 10 にしたことで、以降のrun は 11、dclr は 12 となります。ちなみに、stopは 9 にはならず、0 のままです。, 組み込みマイコンでは、入力の空きポートがあった場合に、そこには何も割り当てたくないので、わざとダミー列挙子を書くか、数値を割り当てなおすことで対応します。, しかし、enumを使わないと、stop, start, run, dclrが相互に関連しているという意図が伝わりにくくなるでしょう。, 列挙型enumについて、お話ししました。関連性のある固定データは、enumを使って、まとめておく方がよいと思います。, そのほうが、さらに追加で関連データが増えても、意識しなくても、+1された値になりますから、意図しない数値にはなりません。, 始めのうちは、あなたの思うようにプログラムを書いてみるといいでしょう。そうしているうちに、どう書くのが最善かを考えるようになってきます。そのときにenumがあったなと思い出せれば、それでよいと思います。, なかなか、ソフトウェアの技術者が入ってこないのと、育つまでに時間がかかるので、一人一人にかかる負荷が非常に大きいです。, 私自身もプログラミング技術を身につけ、仕事に貢献できるようになるまで、3年はかかりました。, しかし、今では日々皆さんが利用しているエレベータのプログラムを最前線で作成しています。. PHP初心者が学習や何かを作ると言った時に関数を調べることがあると思います。 時と場合によりますが、defineがコンパイル前に置き換えると言った点を考えれば使い方が見えてくる気がします。 マクロをただのグローバル定数として使用するだけであれば、const定数と大きな違いはありません。 const定数との決定的な違いはマクロ関 … まあそれはそれとして,constか#defineかについては,英語の議論を見つけました., この中で,Jonathan Leffler (answered Nov 4 '09 at 15:17)の意見が秀逸でした.. これは変数numのインクリメントの実行タイミングが異なるためです。, ひとつの式で同じ変数を二回以上変更する処理を行う場合、動作は未定義となります。 ブログを報告する, pass a pointer aroundの良い訳が思い浮かびませんでした.次の項目と合わせて,「&var」と書けるのは(1)だけ,と解釈しました., http://stackoverflow.com/questions/1674032/static-const-vs-define-in-c. (1) cannot be used as a dimension for arrays at global scope; both (2) and (3) can. *1: pass a pointer aroundの良い訳が思い浮かびませんでした.次の項目と合わせて,「&var」と書けるのは(1)だけ,と解釈しました. *2: gcc-g -std=c89 -pedantic -DOPTION_1 constant.c -o constantとすれば,配列宣言に関して「warning: ISO C90 forbids variable length array 'array'」と警告してくれます. まず用語として,「定数」はCの規格では特定の意味があるのでした.具体的には,JIS X 3010:2003では,定数は「整数定数」「浮動小数点定数」「列挙定数」「文字定数」のいずれかとしています.なので,上のコードのどちらであっても,ledPinを定数とみなすのは,規格から外れた解釈となります. 極端なことを言えばプログラムを停止させるコンパイラがあっても、それは仕様上構わないのです。 Technically, using (1) would imply the use of a VLA (variable-length array), though the dimension referenced by 'var' would of course be fixed at size 5. It is more likely that (2) will not have a symbol, leaving you wondering what it is. コード中では、 const int * を int const * と書きましたが、読みやすさからそうそろえています。int const * は、「整数定数へのポインタ」 (a pointer to a constant integer) 。int const * const は、 「整数定数へのポインタ定数」 (a constant pointer to a constant integer) 。英語だと読み方が逆さまになります。 ですが、switch文のcaseなどで定数を使いたい時はdefineを使わなければなりません。 タイトルに「組み込みC言語の〜」なんて書きましたが、結論は組み込みに限らず最新のC言語での結論と同じになってしまいました。. C言語では型にconstをつけることで、誤って値を代入しようとした場合にコンパイルエラーを発生させることができるが、 ポインタの場合constを置く位置によって変数自体かポインタの指す先かを制御できる。 Toggle navigation Kludge Factory. どのコードを選ぶかは,その値を何に使いたいかによる.3番目の選択肢があることを忘れているよ., なので,多くの状況で,enumを使った(3)は,(1)や(2)よりも良い.別の面では,箇条書きの最初と最後の項目に注意をしたい.同時に両方を満たしたいのなら,よく考えないといけない. 結論. 追記: 使い分けの所を見落としてました。 特に大きく気にするところではありませんが、 constの方がC言語っぽい感じがします。 C++だと,常に,static constの(1)を使えばいい., コードを書いて動作確認してみました.ソースファイルはGistに置いています.mainのほかに2つの関数を定義していて,test_arrayは,varを要素数とする配列の定義,test_switchではvarと定数式としたswitch〜caseを書いています.「static const int var = 5;」を使った方法は,gcc -DOPTION_1 constant.c -o constantによりコンパイルできますが,「error: case label does not reduce to an integer constant」とエラーが出ます*2. 特に大きく気にするところではありませんが、 (1) cannot be used in places like switch statements; both (2) and (3) can. Since (2) is apparently an option, you don't need to pass pointers around. All rights reserved. メールが来ました.学内の先生からです.アルドゥイーノのスケッチのプログラミングで,定数を定義するのに,ある本ではconst intを使っており,また別の本では#defineを使っているのだけれど,夏休みのプログラミング教室で教える際には,どちらのほうが良いのか,とのこと.……, の違い,というわけですが,一般論としては,const intで書く方が,“Cらしい”と言っていいでしょう.