[C++]const int と配列についての疑問

このQ&Aのポイント
  • constについて教えてください。コードをg++ 4.0.1でcompileすると、array bound is not an integer constantというエラーが出ます。
  • (1)(2)ではエラーが出ず、良い結果が得られますが、(3)の場合だけエラーが出る理由がわかりません。
  • どなたか教えてください。
回答を見る
  • ベストアンサー

[C++]const int と配列

constについて教えてください。以下のコード //------------------------------------------------------ #include <stdio.h> #include <math.h> const double RANGE = 12.; const int MESH = 10; //const int N = (int)(12.0*10); // (1) OK //const int N = (int)(12.0*MESH); // (2) OK const int N = (int)(RANGE*10); // (3) NG //const int N = (int)rint(12.0*10); // (4) NG double Array[N]; //------------------------------------------------------ をg++ 4.0.1でcompileすると error: array bound is not an integer constant とでてきます。(1)(2)ではエラーは出ません。 (1)(2)が良くて、(3)がだめな理由がわかりません。 どなたか教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

配列を宣言するときの要素数は, 整数型の定数式が必要です. この「整数型の定数式」に「リテラル」や「整数型の const 変数」は使えるんですが, 「実数型の const 変数」を使うことはできません. そういうものです. ISO だと 5.19 Constant expression のあたりに, この制限が書かれています.

hiwairo
質問者

お礼

ありがとうございます。浮動小数点リテラルをcastして得られるconst intはOKで、浮動小数点const変数をcastしてえられるconst intはNGというのが理解できないなかったのですが、「そういうもの」なのですね。 おそらく、cast計算と配列領域確保のtimingの問題でそういう仕様になっているのでしょうか。 教えていただいた規格を確認してみます。

その他の回答 (1)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.2

No1さんが既に仰っていますが、 「error: array bound is not an integer constant」の通り 配列の添え字が整数の定数では無い為エラーだといっています。 単純に考えて、実数で配列の添え字が扱えるかという問題ですね。

hiwairo
質問者

お礼

ありがとうございます。 「実数で配列の添え字が扱えるかという問題ですね。」 というより実数を整数にcastして得られる静的整数変数がなぜ配列確保に使えないのかという疑問でした。

関連するQ&A

  • C言語の質問です!

    #include "stdafx.h" #include <iostream> #include <string> #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <conio.h> using namespace std; double arrayMin(double array[][], int n){ double Min=9999999999999999999999.999999; for(int N=0;N<n;N++){ if(array[N][0]!=NULL&&array[N][0]<Min){ Min=array[N][0]; } } return Min; } double arrayMax(double array[][], int n){ double Max=-9999999999999999999999.999999; for(int N=0;N<n;N++){ if(array[N][0]!=NULL&&array[N][0]<Max){ Max=array[N][0]; } } return Max; } int main(){ double data[3][10] = {{2.0, 1.0, 5.0, 3.0, 2.0, 21.0, 4.0, 5.0, 4.0, 28.0}, {1.0, 1.0, 5.0, 3.0, 2.0, 21.0, 4.0, 5.0, 4.0, 28.0}, {3.0, 1.0, 5.0, 3.0, 2.0, 21.0, 4.0, 5.0, 4.0, 28.0}}; double min, max; min=arrayMin(data, 3); max=arrayMax(data, 3); printf("min = %lf, max = %lf\n", min, max); return 0; } 二次元配列の1行目の配列の最大値と最小値を求めることを考え,上のようなプログラムを書いたのですが, 1>.\maxmin.cpp(12) : error C2087: 'array' : 添字がありません。 1>.\maxmin.cpp(21) : error C2087: 'array' : 添字がありません。 1>.\maxmin.cpp(34) : error C2059: 構文エラー : ']' 1>.\maxmin.cpp(35) : error C2664: 'arrayMax' : 1 番目の引数を 'double [3][10]' から 'double [][1]' に変換できません。(新しい機能 ; ヘルプを参照) 1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 というようなエラーが出てしまいます. 途中のarray[N][0]!=NULLは二次元配列dataが3行より少ない場合に対応させています. どなたかアドバイスをいただけますでしょうか? よろしくお願いいたします!

  • C++での入出力演算子のオーバーロード

    C++学習者です。Visual Studio 2015 を使っています。 入力演算子>> と出力演算子<<をオーバーロードする関数をfriend としてクラス定義の中に書きましたが、”メンバーではありません” というメッセージが出てきてコンパイルできません。 エラー番号はC2039です。 何回調べても原因がわからないので、詳しい方にお聞きしたいです。 どうかよろしくお願いいたします。 ヘッダーファイルと関数定義ファイル、クライアントプログラムと、エラーメッセージのコピーを張り付けてあります。 // クラスヘッダーファイル // class Array header #ifndef ARRAY1_H #define ARRAY1_H #include <iostream> using namespace std; class Array { // operator overloading as non-member functions friend ostream &operator<<(ostream &, const Array &); friend istream &operator>>(istream &, Array &); public: Array(int = 10); // constructor with default of 10 elements of array Array(const Array &); //copy constructor ~Array(); // destructor int getSize() const; // size of array // operator overloadings as member functions const Array &operator=(const Array &); // assignment bool operator==(const Array &) const; // check equality of two arrays // because both sides of the operator are constant, // this function must be constant too bool operator!=(const Array &right) const { // fully defined function in the header file like this one // will be made in-line function and save overhead time return !(*this == right); } int &operator[](int); // check subscript range for non-constant array const int &operator[](int) const; // check subscript range for constant array // remember we can only invoke constant function of a constant object // so if we want to check the subscript range of a constant object, we need // to use a constant member function of that object, that's why we need a // constant version of the same functionn as above operator[] private: int size; // size of array int *ptr; // pointer to the first element of the array // so ptr is the name of the array }; // end of class Array definition #endif // 関数定義ファイル // array1.cpp // member function definitions of class Array #include "stdafx.h" #include <iostream> #include <iomanip> using namespace std; using std::cout; #include <new> // for new and delete #include <cstdlib> // for exit() using std::exit; #include "array1.h" // >> , << 以外のオーバーロード関数は省略します // input operator overloading istream &Array::operator>>(istream &input, Array &a) { for (int i = 0; i < a.size; i++) input >> a.ptr[i]; return input; } // output operator overloading ostream &Array::operator<<(ostream &output, const Array &a) { int i; for (i = 0; i < a.size; i++) { output << setw(12) << a.ptr[i]; if ((i + 1) % 4 == 0) output << endl; } if (i % 4 != 0) output << endl; return output; } // クライアントプログラム // ConsoleApplication87.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include <iostream> using namespace std; #include "array1.h" int main() { Array integers1(7); // 7 elements array Array integers2; // default 10 element array cout << "size of array integer1 is " << integers1.getSize() << endl; cout << "contents of integers1 after instantiation are :\n"; cout << integers1; cout << "---------------------------------------------\n"; cout << "size of array integers2 is " << integers2.getSize() << endl; cout << "contents of integers2 after instantiation are :\n"; cout << integers2; cout << "---------------------------------------------\n"; return 0; } // エラーメッセージ 1>------ ビルド開始: プロジェクト:ConsoleApplication87, 構成:Debug Win32 ------ 1> array1.cpp 1>c:\users\shiro\documents\visual studio 2015\projects\consoleapplication87\consoleapplication87\array1.cpp(96): error C2039: '>>': 'Array' のメンバーではありません。 1> c:\users\shiro\documents\visual studio 2015\projects\consoleapplication87\consoleapplication87\array1.h(9): note: 'Array' の宣言を確認してください 1>c:\users\shiro\documents\visual studio 2015\projects\consoleapplication87\consoleapplication87\array1.cpp(104): error C2039: '<<': 'Array' のメンバーではありません。 1> c:\users\shiro\documents\visual studio 2015\projects\consoleapplication87\consoleapplication87\array1.h(9): note: 'Array' の宣言を確認してください ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

  • const の使い方

    お世話になります。 VC5.0からVC2005.NETにソフトの移植をしているのですが、 その際、const の使い方で混乱しております。 環境:WinXP、VC2005.NET 以下のコードをビルドするとコンパイルエラーが出てしまいます。 ネットで検索しても、混乱中の上自分のケースに当てはまっているのか どうかさえも怪しい状態でして・・・ --コード-- #include "stdafx.h" class A { public: void func( const int*& a ); }; void A::func( const int*& a ) { return; } int _tmain(int argc, _TCHAR* argv[]) { int *a; A CA; CA.func( a ); ←※ここでエラー return 0; } --ここまで-- --エラー-- error C2664: 'A::func' : 1 番目の引数を 'int *' から 'const int *&' に変換できません。(新しい機能 ; ヘルプを参照) --ここまで-- 基本的なことですがご教授願います。

  • C++のクラス内での2次元配列

    C++学習者です。Windows 10上で、Visual Studio Community 2015 を使って勉強しています。 2次元配列を持つクラスを作ろうとしていますが、クラス定義ファイルの中のプライベート変数部分に2次元配列を定義しようとするとエラーメッセージが出てきます。 自分のソースコードは次のようなもので、最後の int aray[rowSize][colSize]; の部分に赤い波線が出ていて、そこにカーソルを合わせると「静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります。」というメッセージが出ます。 #pragma once #ifndef DSUBARRAY_H // Double Subscripted Array #define DSUBARRAY_H #include <iostream> using namespace std; class DsubArray { public: friend ostream &operator<<(ostream &, const DsubArray &); // output array friend istream &operator>>(istream &, DsubArray &); // input array DsubArray(const int=1, const int=1); // default constructor DsubArray(DsubArray &); // copy constructor ~DsubArray(); // destructor int &operator()(int, int);// subscript -- lvalue const int &operator()(int, int) const; // subscript -- rvalue DsubArray &operator=(DsubArray &);// assignment bool operator==(DsubArray &) const; // equality check of the two arrays bool operator!=(DsubArray &) const; // inequality check int getRowSize() const; int getColSize() const; private: int rowSize; int colSize; int aray[rowSize][colSize]; }; #endif これをたとえば次のように書き換えると、赤い波線は消えるのですが、今度はコラムのサイズが10に固定されてしまい、コンストラクターでこれと異なる数値を与えるとエラーになってしまうのではないかと心配します。 int aray[ ][10]; どなたか2次元配列の正しい作り方を教えてください。お願いいたします。

  • C言語のint型の配列が分かりません

    #include<stdio.h> int main(void) { int str[ ]={0,1,2} printf("%s\n", str); return 0; } というプログラムをC言語でつくってみましたが動きません.(012と表示されて欲しかったのですが) int str[ ]={1,2,3}の部分をchar str[ ]={'0','1','2'}とすれば動きます. そこで質問なのですが, printf("~%s~", (配列名));  はchar型の配列にしか適応できないのですか? ※追記 puts関数の定義は int puts (const char *str); であるそうなので char型の仮引数にはchar型のアドレスを渡さなければいけません. ではprintf関数の定義は一体どんなものなのですか?

  • constの位置

    申し訳ありませんが、続けて質問させていただきます。 char const と const char は同じ意味でしょうか。 次のプログラムは配列をconst charと宣言しています。 ary[1]='N'; の行で、意図した通りにコンパイルエラーになります。 これはchar constと宣言しても、同じ意味なんでしょうか。 #include <stdio.h> int main(void) { const char ary[ ] = { 'A', 'B', 'C', '\0' }; ary[1] = 'N'; printf("aryは%s\n", ary ); return 0; } また、 const int a=1; int const a=1; この2つは同じ意味でしょうか。

  • 配列の動的確保を関数化

    main()内でいくつかの配列を動的確保するとごちゃごちゃするので、 関数化してみました。しかし、下のプログラムではうまい事いきませ んでした。 #include<stdio.h> #include<stdlib.h> void array1d(int *box,int n) { int i; box=(int *)malloc(n * sizeof(int)); for(i=0; i<n; i++) { box[i]=0; } } main() { int *pol,i,n; printf("N pol\nN = "); scanf("%d",&n); array1d(pol,n); for(i=0; i<n; i++) { printf("[%d]=%d\n",i,pol[i]); } } 実行結果は [0]=-14646387 [1]=-1819410433 [2]=-224 array1d内では0を格納していますが、このようになりました。 どのようにすれば 0になるでしょうか? 回答よろしくお願いします。

  • テーブル配列の中身、出力値

    お世話になっております。 C言語勉強中のものです。 一定のひもをランダムに切断し、その長さを測ろうと思っています。 前回アドバイスを頂き、ソートを使って書いてみたのですが、詰まる部分があったのでご指導いただきたいと思いました。 #include <stdlib.h> #include <string.h> #include <stdio.h> #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))   int GetRandom(int min, int max);   int compare_int(const void* a, const void* b);   int compare_str(const void* a, const void* b); int main(void) {   int int_table[] = {GetRandom(0,10000)};   int i;   qsort( int_table, ARRAY_SIZE(int_table), sizeof(int), compare_int );   for( i = 0; i < ARRAY_SIZE(int_table); ++i ) {     printf("%d\n",int_table[i] ); }   return 0; } int compare_int(const void* a, const void* b) {   return ( *(int*)a - *(int*)b ); } int GetRandom(int min, int max) {     return min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX)); } 【困っている箇所】 ・int int_table[]={} の中身に次のようなものを入れることで、ランダムに切ったひもを、ソートできると考えているのですが、その方法を色々ためしましたが上手くいきませんでした。このようなやり方で良いのか、その場合どのようにしたら良いか、また違うのかを教えていただきたいです。 for(i=0;i<10;i++) { printf("%d\n",GetRandom(0,10000)); } ・また最終的にソートしたものを比較させようと思っています。 「出力値を保存する方法」が分からないので教えて頂きたいです。 ----前回ご覧になってくださった方へ---- アドバイスありがとうございました。 まだ初心者ですが、色々ご教授下さるとうれしい限りです。

  • C++の(左辺値)参照を参照渡し

    おそらく基本的なところなのですが 参照を参照で渡すのはNG…? という記述をどっかで見たような見なかったような気がするのですが 再度確認しようと思うも見つからず。 気のせいかもしれません。 または そのときの文章では「参照」という言葉が別の意味で使われていたかもしれませんが 以下のように、左辺値参照を左辺値参照渡しするコードはconst参照、非const参照問わず規格上OKでしたっけ? #include <stdio.h> void func(int& n){ if ( n%7 ){ n+=9; func(n); } else return; } int main(void){ int i = 1; func(i); printf( "%d", i ); return 0; }

  • C++で,配列に計算した値を入れたいです.

    C++で疑似乱数を発生させてサイコロをつくったのですが, サイコロを5回転がしたときのそれぞれの値をソートしたいと思い,配列に入れれば簡単だと考えてとりあえず配列に入れるプログラムを書いてみました. しかし,int array[i] = Dice(); のところでエラーが出てしまいます. ローベルのC++入門講座という本を使って独学で勉強している初心者なため,配列の使い方がいまいちよくわかりません. ご教授よろしくお願いします. 以下ソースコード #include <iostream> #include <cstdlib> #include <ctime> using namespace std; void InitRand(){ srand((unsigned int) time (NULL)); } int Dice(){ return rand() % 6 + 1; } int main(void){ int n = 0; //nはサイコロを転がす回数 cout <<"サイコロを何回転がしますか?" << flush; cin >> n; cout << "回転がします" << endl; InitRand(); for(int i = 0; i < n; ++i){ cout << Dice() << endl; int array[i] = Dice(); //エラーが発生する.i回目のサイコロの値をi番目の配列に入れたい. } }

専門家に質問してみよう