質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

解決済

c言語の配列とデータ型

kjhoh
kjhoh

総合スコア4

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

3回答

0グッド

0クリップ

372閲覧

投稿2022/11/21 15:29

実現したいこと

c言語で以下のソースコードを書いていた時に、16行目の配列x[],y[]にそれぞれ配列の要素数としてscanfで入力したnを入れようとしたとき未知数であるためコンパイルできないというエラーが出ました。この問題を解決することはできないのでしょうか?
また、、16行目の配列x[],y[]にそれぞれ配列の要素数として以下のように定量的な値として、1000000と入れたらプログラムが動かないという問題が発生しました。10000としたときは動いたため、データ型等に問題があるのかと考えましたが、計算途中でもdoubleの範囲を満たしているように見えるため、なぜ動かないかわかりません。
この問題の原因も教えてもらえると嬉しいです。

該当のソースコード

ソースコード #include <stdio.h> int main(void) { int n,i,j,sou,kukaku; i= 0; j= 0; double m; printf("Please input a positive integer.\nn = "); scanf("%d",&n); while(0 < n) { sou=n*n; kukaku=0; double x[20000],y[20000]; while(i < n) { x[i]=(((1.0/n)*i)+((1.0/n)/2)); while(j < n) { y[j]=(((1.0/n)*j)+((1.0/n)/2)); if(((x[i]*x[i]) +(y[j]*y[j])) <= 1) { kukaku++; } j++; } j=0; i++; } printf("総分割数=%d\n",sou); printf("求める区画数=%d\n",kukaku); printf("pi = %.4lf\n",kukaku*4.0/sou); printf("Please input a positive integer.\nn = "); scanf("%d",&n); i=0; j=0; } return 0; } ### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

2022/11/21 22:58

こちらの質問が他のユーザーから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました。

回答3

4

ベストアンサー

動的な配列は古めの c ではできません。
ローカル変数領域はそんなに大きくありません。
どちらの解決にも、 malloc() 等を使用してください。

メモリの動的確保(配列など)

投稿2022/11/21 19:56

編集2022/11/21 20:04
jimbe

総合スコア10748

spoofy_dragon, BeatStar, pig_vba, maisumakun👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

1

エラーメッセージは「雰囲気」で読んでいると時々痛い目を見ます。また、コミュニケーションミスを防ぐためにも、質問においてはエラーメッセージは意訳や自分の解釈でなく「出たまま、見たまま」を提示していただきたいと思います。
「未知数であるため」というのは正確ですか? 想像すると「定数式が必要です。」だったのでは。

Cでは、1999年版の規格から配列の宣言時の要素数に変数が使えることになりました。しかし、(多分某一社の抵抗により)その規格は2011年版(だったっけ?)からオプション(対応しなくてもいい)にランクダウンしています。多分質問者さんはその某一社のCコンパイラを使っているのかと思います。
(あるいは、C++では配列の宣言時の要素数は定数でなければいけないので、CのプログラムをC++としてコンパイルしている可能性はありますが)
なので、

この問題を解決する

について(だけ)言えば、要素数に変数を使えるgcc, clang等のコンパイラを採用し、(C++ではなく)Cとしてコンパイルするのが一つの方法です。
コンパイラを変更したくないのなら、jimbeさんが回答しているように、mallocなどを使って自分でメモリを取得してその領域を使うことになるでしょう。

ただし。ローカル変数(関数内で宣言する変数)は、効率や管理の面から「スタック」領域にとられます。スタックは関数呼び出しのときに戻る場所をあくまで一時的な小容量データの退避場所であって、大容量のデータを保存する場所として考えられたものではありません。そのため、現在のWindowsやLinuxでもプログラム全体を通して(デフォルトで)1~2MB程度しか確保されていません。doubleは変数1つあたり8byteを使うのが普通ですから、これを1000000個確保したらそれだけで約8MB, 完全に破綻します。ということで、そもそもその配列の確保の方法は(文法的にエラーを出ないようにしたとしても)ダメ、ということ。
対応案としては、

  1. 要素数の最大値の予想はできるのでしょうか。できるのであれば、最初からその最大値で配列を(関数の外で/グローバル変数として)確保してしまって、余った分は使わない、という手段は考えられます。まぁ、あまりに無駄な確保が多すぎる(GBのオーダーとか)とコンピュータ全体の動作に支障をきたす可能性はありますが。
  2. どうしても「指定されただけ」しか確保したくないというなら、先程の話で出ていたmalloc等による確保をするのがもう一つの方法です。mallocによるメモリ確保はスタックとはまたべつの「ヒープ」という領域を使いますが、これは大容量を使えるのが普通ですので。もちろん、コンピュータが扱えるメモリ量を超えてはだめですけれど。

投稿2022/11/23 10:02

thkana

総合スコア7323

kjhoh👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

1

一般的にローカル変数はスタック領域に配置されるため、そんなに大きなサイズは確保できません
グローバル変数にしましょう

投稿2022/11/21 23:03

y_waiwai

総合スコア86005

spoofy_dragon👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

2022/11/22 18:53

こちらの回答が他のユーザーから「説明が不足している回答」という指摘を受けました。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。