お世話になります
初歩的な事ですがよろしくお願い致します
const 修飾子って変数型の前につけるの?後につけるの?
//----------------------------------------------------
const int iTest1[] = { 0x0000, 0x0000 };
const int iTest2[] = { 0xFFFF, 0xFFFF };
const int* const piTest[] = { iTest1, iTest2 };
//----------------------------------------------------
const int 型のポインタ配列をロム領域に確保したい場合は変数の後にconst修飾子をつけると思います
const const int* piTest[] = { iTest1, iTest2 };
これだとエラーとなるはずです。。。
そこで、疑問に思ったのが、私の書式だと、const intとconst修飾子は前に着けるのが普通だと思ってました
//----------------------------------------------------
const int i = 0;
int const i = 0;
//----------------------------------------------------
でも、どちらでもコンパイルは通ると思います
配置領域を確認した所、どちらもROMに確保されてました
一般的にどちらが正解なのでしょうか?
const const int* piTest[] = { iTest1, iTest2 };
が、エラーになるという事は、int const i が正解なのでしょうか?
教授よろしくお願い致します
ちなみに、組み込み系に特化した話になっています
windows系とかだとconst宣言は何処にいくんですかね・・・
ヒープじゃない予備領域とかあるんですかね・・・
No.1ベストアンサー
- 回答日時:
> const int* const piTest[] = { iTest1, iTest2 };
これは、
(const int*) const piTest ...
の意味ですね。(正しい文法ではカッコは付けられません)
piTestそのものを修飾するには、constは必ず後ろに付けなければなりません。
> const const int* piTest[] = { iTest1, iTest2 };
> これだとエラーとなるはずです。。。
C90ではエラーですが、C99ではエラーになりません。(警告は出るかもしれません)
実際のところ、どの構成要素を修飾するのかが明確であれば、修飾子は前でも後でも真ん中でもかまわないのです。
const unsigned int x;
unsigned int const;
unsigned const int x;
これらは、どれでもOKです。
もし、どの構成要素を修飾しているのかがよく分からないのであれば、修飾子は必ず後ろに付ける方が無難です。
> どちらもROMに確保されてました
> ちなみに、組み込み系に特化した話になっています
組込みでもPCでも関係ありません。
書き換え不可の静的オブジェクトをどこに配置するかは、リンカの設定で決まります。組込みでも、起動時にROMやフラッシュメモリからいったんRAMに展開することもあるように、PCの場合でもいったんディスクからメインメモリに展開することになります。
No.2
- 回答日時:
constの位置について、「C言語ポインタ完全制覇」という書籍に詳しく書かれています。
これによると、constはその直後にあるものを修飾するとの事です。具体的には、int const foo;
ではfooがconstになるので、fooの値が変えられません。また、
int * const foo;
ではfooがconstになるので、
*foo = 100;
はOKだけど
int x;
foo = &x;
はNGになります。
int const * foo;
では*fooがconstですので、int * const fooの場合と逆になり、
*foo = 100;
がNGになります。さらに、両方をconstにするには
int const * const foo;
になります。ここで、ややこしいことに、先頭のみ(この例ではint)例外的にconstの位置を入れ替えて、
const int foo;
や
const int * const foo;
とすることができるとのことです。つまり、「基本的には後ろにconstをおいて、例外的に先頭のみ前に置くことができる」と覚えると混乱しないようです。また、常に後ろにつけるという方法もあると思います。
No.3
- 回答日時:
細かなことはNo1,No2さんが書かれていて正しいと思うので、これ以上は省くけど、
15年以上Cでプログラミングしてきましたが、仮に文法的に正しいとしても、int const i てのは見た記憶ないですよ。
やっぱ const int i じゃないっすか。
そっちの方が、int i は const(変更不可)なんだぞ! というプログラマの意志が伝わってきますし。(少なくとも私はそう感じます)
それに複数の const の変数があった場合、
const int i;
const char a;
...
の方が、constが揃っていて、パッと見で見やすくないですか。
ああ、この変数一群は全部 const なんだなと把握しやすいですよ。
No.4
- 回答日時:
> constが揃っていて、パッと見で見やすくないですか。
> ああ、この変数一群は全部 const なんだなと把握しやすいですよ。
その考え方は危険だと思いますよ。
const int a;
const char *b;
int (* const c)(int);
を、その基準でパッと見で判断すると、間違いなく事実誤認につながります。
単純なものはconst intのようにすればよいと思いますが、よく見ずに、脊椎反射的に型を判断してしまうのは、やはりまずいのではないでしょうか。
ちなみにC++であれば、
template<class C, class Traits, class Allocator>
void func(std::basic_ostream<C, Traits>& ostr, std::basic_string<C, Traits, Allocator> const& str)
{
...
}
のように、型名が非常に長くなる傾向にありますので、修飾子は後ろに付けるようにしないと、見辛くて仕方ありません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# ポインタの型変換、どうやるんでしたっけ? 2 2022/03/28 11:00
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- JavaScript WordPressのコンタクトフォーム7にて送信者の位置情報を送らせたい 2 2022/09/14 23:28
- JavaScript Javascriptが機能せず原因が分からないので教えて頂きたいです 3 2023/06/04 14:50
- JavaScript vertical sliderをautoplayしたい 2 2022/08/25 14:47
- C言語・C++・C# Cの関数の引数のconst *charについて 5 2023/04/25 13:05
- Access(アクセス) Vba Userformを前面に出すについて 3 2022/04/15 12:29
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
戻り値を返す関数の前に(void)...
-
C++にてtemplateで受け取った任...
-
【gcc・cygwin】multiple defin...
-
Notepad++の関数リスト表示の変...
-
int main()、void main()、void...
-
C# KeyDownイベントでショート...
-
ArduinoでMouse関数を使用して...
-
ドラッグしたときにマウスカー...
-
多重定義が起きている?--lnk20...
-
合格か否かを表示するプログラ...
-
typedef unsigned int UINT;が...
-
構造体を宣言と共に初期化する方法
-
C++別のオブジェクトからメンバ...
-
VC++でGetKeyboardStateがうま...
-
C# Controls.Addで動的に配置し...
-
C#でラジオボタンを設定に記録...
-
void*型の配列について
-
gcc: incompatible pointer type
-
マルチメディアタイマーの使用方法
-
DLLの関数呼び出しで引数がある...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
int main()、void main()、void...
-
戻り値を返す関数の前に(void)...
-
既定のコンストラクタがありま...
-
Notepad++の関数リスト表示の変...
-
ArduinoでMouse関数を使用して...
-
多重定義が起きている?--lnk20...
-
C++にてtemplateで受け取った任...
-
静的でないメンバ関数の呼び出...
-
C# Controls.Addで動的に配置し...
-
const_castのつかいどころを教...
-
(void)0 はどんな意味ですか
-
C# KeyDownイベントでショート...
-
gcc: incompatible pointer type
-
C#でラジオボタンを設定に記録...
-
VC++でGetKeyboardStateがうま...
-
C言語 ① 5秒間 1秒間隔で点滅を...
-
void*型の配列について
-
GDI+の使用方法について
-
DirectInput でのエラー
おすすめ情報