4

Java を 2 年間使用した後、約 3 週間前に C++ の学習を開始しました。とても違うようですが、私はそこに着いています。私の講師は素敵な人ですが、何かがなぜそのようであるか、またはこのようであるかについて質問するときはいつでも. 彼はただ「そうだから」と答えます。

以下のコードには、いくつかのランダムな質問を含む多くのコメントがありますが、主な問題は、2 つのビルド エラーが発生することです。メインで。

誰かがコードを読んで、その中のいくつかのコメントに答えてくれませんか?おそらく全体的な問題はありますか?

#include<string>
#include<fstream>
#include<ostream>

using namespace std;

//double decimals[5] ={2,4,6,8,10};

const int arraySize = 5;
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?

//double decimals[arraySize];

/*
   this array is being created in the function averageN() but why?
   cant i just create it up top and reference it in?
 */

// why do you have to write the name of the function up here before you even create it?
double averageN();

int main()
{
    averageN();
    return 0;
}

// why does the array have to be created here?
double averageN(double decimals[arraySize])
{

    double average;
    double arrayTotal;
    for (int i = 0; i<5;i++)
    {
        // fills with random numbers from 0 - 10
        decimals[i] = (0+(rand()%10));
    }

    // find the total of all the elements in the array
    for (int i = 0; i < arraySize;i++)
    {
        double currentElement = decimals[i];
        arrayTotal = (currentElement+arrayTotal);
        //arrayTotal +=decimals[i]) ;
    }
    // return the average
    average = (arrayTotal/arraySize);
    return 0.0;
}
4

8 に答える 8

6
  1. // arraySizeは常にconstである必要がありますか?アレイが作成された後に変更されないようにするためですか?はい、constである必要があります。さらに、定数式である必要があります。つまり、そのサイズはコンパイル時(実行時ではなく)に認識されている必要があります。配列のサイズを変更する場合は、標準のコンテナーstd::vectorを使用するのが最適です。または、固定サイズの配列が必要な場合は動的に割り当てられた配列を使用しますが、実行時までサイズはわかりません

  2. / *この配列は関数averageN()で作成されていますが、なぜですか?一番上に作成して参照することはできませんか?* /小数について言えば、いいえ、それはグローバル変数であり、どこからでも使用できます。

  3. //関数を作成する前に、関数の名前をここに書き留める必要があるのはなぜですか?使用する前に、C++で任意の名前を宣言する必要があります。この関数はmainで呼び出すため、少なくとも事前に宣言する必要があります。mainの前に定義(本体)を指定することもできます。

  4. //なぜここで配列を作成する必要があるのですか?

おっと、コードに大きな混乱があるようです。実際のところ、averageNという名前の2つの関数があります。1つはパラメーターをとらないaverageNで、もう1つはdoubleの配列をとるAveraeNです。最初の関数を定義したことはなく、宣言したばかりです。

エラー:

  1. doubleTotalは初期化されていません。まあそれはに double arrayTotal; 変更されていません

    double arrayTotal = 0.0;

  2. mainの未解決の外部-これは、メインのAverageN関数です。あなたはそれのために体を書いたことはありません。配列を受け取る関数を作成しましたが、配列はグローバルであるため役に立ちませんでした。AverageN定義から配列パラメーターを削除するだけです。

HTH

PS ReadS.LippmannのC++入門書。初心者向けの最高の本であり、C++向けです。IMO :)

于 2010-10-13T13:38:31.687 に答える
2
  • constは、項目を変更してはならないという手がかりをコンパイラーに与え、コードがそれを試みた場合、コンパイラーはエラーにフラグを立てることができます。

  • 関数名は、実際の宣言の前に記載されています。main()関数は、コンパイラが実際にコンパイルする前に、関数を参照する必要があります(後でコードファイルで説明します)。これを回避するために、関数全体をmain()の前に移動できます。

  • double averageN(double decimals [arraySize])は、この関数が配列を取ることを示しています。アレイを作成するとは言いません。関数を見ると、配列を取得し、計算された値を配列に追加します(decimals[i] = (0+(rand()%10)))。この関数は、配列全体の平均も計算し、それをdoubleとして返します。

それで、あなたの大きな質問に答えるために、何が悪いのか-最後のポイントを読んで、あなたがかけている電話を見てaverageN();ください---これがどのように正しい電話ではないかを見ることができますか?

于 2010-10-13T13:32:34.553 に答える
1
  const int arraySize = 5;
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?

type name[size]C ++は基本的に、として宣言される固定サイズの配列と、で割り当てられる動的配列の2種類の配列をサポートしますnew[]
固定サイズの配列の場合、配列に十分なメモリを確保できるように、コンパイラにサイズを指定する必要があります。constサイズはコンパイラーに認識されている必要があるため、変数またはリテラルでのみ指定できます。
動的に割り当てられた配列を自分で作成することは可能ですが、を呼び出すことによりnew[]、メモリ管理を正しく行うためのいくつかの問題が発生します。のように、これを行う既存のクラスを使用することをお勧めしますstd::vector

 //double decimals[arraySize];

/*
 this array is being created in the function averageN() but why?
 cant i just create it up top and reference it in?
 */

ここで作成できますが、それによって誰でもアレイにアクセスできるようになります。このような小さなプログラムの場合、これは大きな問題ではありませんが、配列にアクセスして予期しないときに変更できるファイルが他にも12個あることを考慮してください。

基本的に、Javaですべてのクラスとメンバーを公開しない理由と同じ質問です。アクセスできるユーザーを制限するためです。

// why do you have to write the name of the function up here before you even create it?
double averageN();

使用する前に、関数を宣言する必要があります。C ++には、使用するすべての名前が最初に使用する前にコンパイラーに宣言されている必要があり、コンパイラーはファイルを上から下に順番に読み取る必要があります。

この宣言は、以下で指定する関数定義と一致しないことに注意してください。C ++は関数のオーバーロードをサポートしているため、2つは異なるパラメーター(なしとポインター)を受け入れるため、異なる関数と見なされます。

 int main()
 {
    averageN();
    return 0;
 }

 // why does the array have to be created here?
 double averageN(double decimals[arraySize])
     {

これは配列を作成しません。代わりに、関数がポインター引数で呼び出されることを期待することを指定します(これarraySizeは完全に無視され、C ++では関数に配列を渡すことができないため、パラメーターは読み取りに調整されますdouble *decimals)。

動作するプログラムを取得するには、上記の2行を次のように変更する必要があります。

 double averageN()
     {
    double decimals[arraySize];

double average;
double arrayTotal;

averageとは両方ともarrayTotal初期化されていません。つまり、未知の値から開始するということです。
の場合average、これは問題ではありません。最初に行うのは、新しい値を割り当てることだからです。ただしarrayTotal、の場合は値を追加するため、既知の値で開始する必要があります。

for (int i = 0; i<5;i++)
{
    // fills with random numbers from 0 - 10
    decimals[i] = (0+(rand()%10));
}

// find the total of all the elements in the array
for (int i = 0; i < arraySize;i++)
{
    double currentElement = decimals[i];
    arrayTotal = (currentElement+arrayTotal);
    //arrayTotal +=decimals[i]) ;
}
// return the average
average = (arrayTotal/arraySize);
return 0.0;
 }
于 2010-10-13T14:00:14.490 に答える
1

OK、これが arrayTotal への唯一の割り当てです。

 arrayTotal = (currentElement+arrayTotal);

arrayTotalでは、この代入後の の値は何ですか? まあ、それは割り当て前の値に依存します。最初の割り当ての前に、その値は何でしたか? あなたは知りません。初期値を指定したことがないため、何でもかまいません。

于 2010-10-13T13:45:08.720 に答える
0

他の回答の技術的な詳細に加えて、代わりに最初の段落で苦情に回答します。「なぜ」C++ の質問に対する質の高い回答を得る 1 つの方法は、Usenet グループの 1 つで質問することです。専門家がぶらぶらしていますが、StackOverflow とは異なり、初心者の質問でも標準化委員会のメンバーから回答を得られる可能性が高く、運が良ければ標準を作成した人 (Andrew Koenig や現在の Pete Becker など) から回答を得ることができます。以前は、Bjarne もそこにいました。しかし、ここ数年、彼はあまり投稿していません。

基本的な初心者の「なぜ」の質問: alt.comp.lang.learn.c-c++ . Francis Glassborow がそこにたむろしています。彼は委員会のメンバーであり、成功を収めた C++ の入門書を何冊か執筆しています。彼は数学にも少し精通しており、投稿頻度が低いため (StackOverflow のおかげで!)、中途半端な興味深い質問には、Francis がすぐに (そして正確に) 答えてくれるとほぼ確信しています。:-)

C++ 言語に関する一般的な質問: comp.lang.c++および/またはcomp.lang.c++.moderated。後者のグループはモデレートされており、チャーターがあります。モデレートはノイズを減らします (たとえば、スパムはありません) が、遅延が追加されます。一部の委員会メンバーは主にモデレートされていないグループ (例: James Kanze) に投稿することを好み、一部の者 (Pete Becker や Howard Hinnant など) は両方のグループに投稿します。

標準の意味に関する質問、標準のエラーに関する報告など (以前は、標準の欠陥を正式に報告する場所でもありました): [comp.std.c++]。これはモデレートされたグループでもあり、残念なことに、モッドの遅延はほとんど耐えられないほど長くなりました. しかし、初心者としては、おそらく正式な詳細にはあまり興味がなく、[comp.lang.c++] と [comp.lang.c++.moderated] が優れたグループである理論的根拠と説明に関心があるでしょう (StackOverflow のメイン利点は、「このコードのバグは何ですか」または関連するドキュメントを読むだけで原則的に解決できる質問がある場合です)。

最後に、Web ベースのインターフェイスを提供する Google グループにリンクしましたが、これらのグループには、Thunderbird などの Usenet クライアント (またはクライアントが組み込まれている Opera ブラウザーなど) から直接アクセスできます。ローカル クライアント経由で Usenet にアクセスするために必要なことは、無料の EternalSeptember などのサーバーについてクライアントに通知するようにクライアントを構成することだけです。またはAIOE。

乾杯 & hth.,

– アルフ

于 2010-10-13T15:04:16.140 に答える
0

いくつかの問題:

  • averageN の前方宣言が正しくありません

コード:

double averageN();

以下に提供されているバージョンは、パラメーターを取ります。

  • averageN の宣言はうまく機能しません
    配列型のパラメーターを宣言することは、直感的に明らかではありません。
    通常、人々は配列を配列へのポインターに分解し、長さを 2 番目のパラメーターとして渡します。

コード:

double averageN(double *decimals, int arraySize)

特定のサイズの配列のみを渡したい場合は、参照によって行う必要があります。

double averageN(double (&decimals)[arraySize])
  • メインの averageN() への呼び出し。
    パラメータを渡していません。これは前方宣言と一致しますが、実際の定義とは一致しません。

結果コードを次のように変更します。

extern double averageN(double (&decimals)[arraySize]);

int main()
{
    double data[arraySize];
    averageN(data);
    return 0;
}

// why does the array have to be created here?
double averageN(double (&decimals)[arraySize])
{
于 2010-10-13T13:50:17.757 に答える
0

ダブルチェックなしの私の簡単な答え(C ++で開発してからしばらく経ちました)は次のとおりです。

  1. arraytotal が初期化されていません

    コンパイラがこれをエラーとしてフラグ付けして、確実に実行していると思われます。そうしないと、何に初期化されるかわかりません。従来、デバッグ ビルドでは、C/C++ はメモリをデバッグ値に初期化して、初期化されていない変数を識別できるようにしていました。初期化時に arrayTotal = 0 を設定すると、それはなくなるはずです。(ベストプラクティス)

    例 double arrayTotal = 0;

  2. メインの外部参照

    これは、 averageN のプロトタイプが後で定義されたメソッドと一致しないためだと思われます。プロトタイプには、パラメーターの型と戻り値の型を含める必要があります。double averageN();からプロトタイプを変更します。averageN(double [])を2 倍にします。そして、それがその問題を解決すると信じています。

  3. arraySize は常に const である必要がありますか? 配列が作成された後も変化しないのですか?

    averageN に渡される配列のサイズを定義するために使用しているので、はい。このように配列のサイズを設定するには、定数値が必要です。

  4. この配列は関数 averageN() で作成されていますが、なぜですか? 一番上に作成して参照することはできませんか?

    averageN では作成されていません。averageN への正式なパラメータです。averageN の呼び出し元は、適切な変数を提供してそれを渡す必要があります。次に、メソッド内から 10 進数でアクセスします。

  5. 関数を作成する前に、なぜここに関数の名前を書かなければならないのですか?

    これが関数のプロトタイプです。関数が定義される前に関数がコードで参照される場合に必要です。これは、すべての使用前に averageN の定義を移動するなど、他の方法でも解決できます。

于 2010-10-13T13:49:41.910 に答える
0

誰もコメントしていないように見えることの 1 つは、最後の return ステートメントaverageNが間違っていることです。平均を返していると言ってから、半径を計算してからreturn 0.0;. return average;またはを試してくださいreturn arrayTotal/arraySize;

于 2010-10-13T19:14:51.237 に答える