毎度お世話になっております、山崎です。
今回は、配列を宣言した時の要素数や、関数の引数に配列を渡すときなどについて質問に参りました。
XPでVisual Stadio2008を使っております。
現在、他人からもらったC言語のプログラムを読み解いています(ゲームとは関係ないのですが)。
その人が言うにはちゃんと動くらしいのですが、私のパソコンでビルドしてもエラーが発生します。
もらったのは.cppではなく.cのファイルをひとつです。
コードを見ると、不思議な配列の宣言のやり方をしていて、私にはどうも理解できません。
その人が作ったプログラムをそのままここにコードを貼る訳には行かないので全てはコピーペーストできませんが、
エラーの起きている行をいくつか挙げてみます。
void func(int a, int pal1[a],float pal2[a],float pal3[a]);
これは関数プロトタイプで、ファイルの最後にこの関数の動作の定義があります。
もちろんaは定数ではありません、この行で初登場です。
引数として配列を渡しているように見えますが、[/url]内に変数を持ってきて、そんな配列を引数にできるんでしょうか?
「定数式が必要」「サイズが0の配列を割り当てまたは宣言しようとしました」というエラーが出ます。
int Val1[CONST][count+1][5];
CONSTは定数で既に数値として定義されています。countはint型の変数として事前に宣言されています。
int型の3次元配列を宣言しているように見えますが、宣言時には[/url]内には変数は持ってこれないのでは?
と首を傾げています。
「定数式が必要」「サイズが0の配列を割り当てまたは宣言しようとしました」「添え字がありません」
といったエラーが出ます。
int Val2[(x+1)*(x+1)*CONST][5];
CONSTは定数で既に数値として定義されています。xはint型の変数として事前に宣言されています。
これはint型の2次元配列を宣言しようとしているように見えるのですが、
これも[/url]内に数式があります。こんなことはできましたっけか…。
「サイズが不明」というエラーが出ています。
なにぶん他人の作ったプログラムなのでそのまま載せられず、前後関係がつかめずわかりにくいとは思いますが…。
これらの行でエラーになるのは当然なのではないだろうかと思うのですが、
これらのコードでもちゃんと実行できることがあるのでしょうか?
VisualStadio以外の特殊な環境や特殊なコンパイラを使えば実行できる、など…。
配列宣言時の要素数の指定について
Re:配列宣言時の要素数の指定について
[color=#d0b0c0" face="monospace]
>これらのコードでもちゃんと実行できることがあるのでしょうか
[/color]
今の Visual C++では出来ませんが、最新の Cの仕様(C99)を満たした
コンパイラなら一応可能です。
プログラミング言語 C の新機能
ttp://seclan.dll.jp/c99d/c99d00.htm
試しに a.cとしてサンプルを書いて gcc4.2.1でコンパイルしてみました。
[color=#d0d0ff" face="monospace]
#include<stdio.h>
#define CONST 5
int func(int a, int pal1[a],float pal2[a],float pal3[a]);
int main(void)
{
int count;
printf("input count > ");
if(scanf("%d", &count) == 1 && count >= 0)
{
int Val1[CONST][count+1][5];
for(int i=0; i<CONST; ++i)
{
for(int j=0; j<count+1; ++j)
{
for(int k=0; k<5; ++k)
Val1[j][k] = i + j + k;
}
}
int p[count];
float f1[count], f2[count];
printf("count + 1 = %d\n", func(count, p, f1, f2));
}
else
printf("error\n");
return 0;
}
int func(int a, int pal1[a],float pal2[a],float pal3[a])
{
return a + 1;
}
[/color]
gccのオプションに -std=c99をつける必要はありますが、問題なくコンパイルは通りました。
もちろん、実行もできました。
[color=sans-serif]
input count > 89
count + 1 = 90[/color]
>これらのコードでもちゃんと実行できることがあるのでしょうか
[/color]
今の Visual C++では出来ませんが、最新の Cの仕様(C99)を満たした
コンパイラなら一応可能です。
プログラミング言語 C の新機能
ttp://seclan.dll.jp/c99d/c99d00.htm
試しに a.cとしてサンプルを書いて gcc4.2.1でコンパイルしてみました。
[color=#d0d0ff" face="monospace]
#include<stdio.h>
#define CONST 5
int func(int a, int pal1[a],float pal2[a],float pal3[a]);
int main(void)
{
int count;
printf("input count > ");
if(scanf("%d", &count) == 1 && count >= 0)
{
int Val1[CONST][count+1][5];
for(int i=0; i<CONST; ++i)
{
for(int j=0; j<count+1; ++j)
{
for(int k=0; k<5; ++k)
Val1[j][k] = i + j + k;
}
}
int p[count];
float f1[count], f2[count];
printf("count + 1 = %d\n", func(count, p, f1, f2));
}
else
printf("error\n");
return 0;
}
int func(int a, int pal1[a],float pal2[a],float pal3[a])
{
return a + 1;
}
[/color]
gccのオプションに -std=c99をつける必要はありますが、問題なくコンパイルは通りました。
もちろん、実行もできました。
[color=sans-serif]
input count > 89
count + 1 = 90[/color]
Re:配列宣言時の要素数の指定について
> gccのオプションに -std=c99をつける必要はありますが、問題なくコンパイルは通りました。
それは for で宣言しているからです。
GCCはもともと可変長配列を独自拡張としてサポートしています(標準規格がそれに追従したのですから)。
ですので、特にオプションを指定しなくても可変長配列を使えます。ただし、自動記憶域期間を持つ配列の場合だけです。
それは for で宣言しているからです。
GCCはもともと可変長配列を独自拡張としてサポートしています(標準規格がそれに追従したのですから)。
ですので、特にオプションを指定しなくても可変長配列を使えます。ただし、自動記憶域期間を持つ配列の場合だけです。
Re:配列宣言時の要素数の指定について
[color=#d0b0c0" face="monospace]
>GCCはもともと可変長配列を独自拡張としてサポートしています
[/color]
あ、たしかにそうですね、忘れてました。
-pedanticもつけてあげればいいですかね?
>GCCはもともと可変長配列を独自拡張としてサポートしています
[/color]
あ、たしかにそうですね、忘れてました。
-pedanticもつけてあげればいいですかね?
Re:配列宣言時の要素数の指定について
Justyさん、たかぎさん
ご返信、誠にありがとうございます!
gccでコンパイルしたところ、見事に実行ファイルを作ることができました。
しかし、コンパイラの違いでこんなことができてしまうなんて驚きです。
コンパイラの違いなんて、せいぜい警告が出るか出ないかくらいだと思っておりました。
非常に勉強になりました。
…VisualStudioでもできるようになればいいんですけどなぁ…。
本当にありがとうございました。
ご返信、誠にありがとうございます!
gccでコンパイルしたところ、見事に実行ファイルを作ることができました。
しかし、コンパイラの違いでこんなことができてしまうなんて驚きです。
コンパイラの違いなんて、せいぜい警告が出るか出ないかくらいだと思っておりました。
非常に勉強になりました。
…VisualStudioでもできるようになればいいんですけどなぁ…。
本当にありがとうございました。