6

次のコードが正しくない理由について、作成者が手続き的にではなく宣言的に C++ コードを書こうとしているという理由について、どうすれば適切な説明を作成できるでしょうか?

const double NEWTONS_PER_POUND = 4.448;

int main()
{
   double pounds, newtons;
   pounds = newtons/NEWTONS_PER_POUND; /* pounds equals 'unassigned variable'/4.448 */
   newtons = 10.0;
   cout << pounds << endl;             /* a big number, not 10.0/4.448 */
   return 0;
}

著者coutは適切な計算を表示することを期待していましたが、代わりに「狂った数」を取得しました。

これについては、「C++ は手続き型であるため、宣言の時点で

pounds = newtons/NEWTONS_PER_POUND;

newtons値が割り当てられていません。

より良い提案はありますか?あるいは、C++ が、ユーザーが誤って期待した動作を実行するほど「スマート」ではない理由を説明しますか?

4

9 に答える 9

21

作者にそう言えよ

pounds = newtons/NEWTONS_PER_POUND;

CPUに命令する

  • 「ニュートン」と呼ばれるアドレスの値を取る
  • 「NEWTONS_PER_POUND」と呼ばれるアドレスの値を取る
  • それらを分割する
  • 「ポンド」と呼ばれるアドレスに結果を保存します

彼が探しているのは、おそらく命令用語の関数です。

double newtons_to_pounds(double newtons) {
  return newtons/NEWTONS_PER_POUND;
}

...

newtons = 10.0;
cout << newtons_to_pounds(newtons) << endl;    /* a big number, not 10.0/4.448 */
return 0;
于 2009-09-01T06:53:42.500 に答える
18

C++ は、方程式ソルバーではなく、命令型プログラミング言語です。

C++ は、記述した順序でステートメントを実行します。C++ は、指示がない限り変数を初期化しません。C++ では、値が初期化されていない変数を使用できますが、これを行うと、結果はunspecifiedになります。不特定とは、「クレイジーな数字」を生成するなどの悪いことを含め、あらゆることが起こり得ることを意味します。

詳細な説明は次のとおりです。

double pounds, newtons;
pounds = newtons/NEWTONS_PER_POUND;
newtons = 10.0;

最初のステートメントは、2 つの変数を初期化せずに宣言します。この時点では、それらの値は指定されていません。

2 番目のステートメントはnewtons(何でもかまいません) の値を読み取り、それを で割りNEWTONS_PER_POUNDます。結果 (何でもかまいません) は に割り当てられpoundsます。

3 番目のステートメントは を初期化しますnewtonsが、今実行した計算に影響を与えるには遅すぎます。

于 2009-09-01T06:56:03.057 に答える
8

学生のバックグラウンドに関係なく、説明するのはそれほど難しいことではありません。C++ がプログラムを一度に 1 ステップずつ、ステートメントごとに評価することだけです (並べ替えなどのコンパイラのアーティファクトにもかかわらず…)。

これを処理する C++ の方法に特別なことは何もありません。また、コンピューター プログラミングに限定されているわけでもありません。むしろ、命令の順序付きリストを処理する日常的な方法です。

于 2009-09-01T06:55:53.230 に答える
4

ニュートンを評価するのは怠惰ではありません

そのため、計算は要求時ではなく、宣言時に実行されます。彼は、C++ が行うことではなく、機能的なコードを求めています。

于 2009-09-01T06:45:04.530 に答える
4

その人が過度に技術的でない場合は、次のことを試すことができます。

「この C++ プログラムのステートメントは、ケーキを作るのに必要な手順のようなものです。成功するには、手順を 1 つずつ実行する必要があり、特定の順序で実行する必要があります。」

于 2009-09-01T06:58:40.353 に答える
1

代入演算子を使用して行でポンドに値が割り当てられることを説明します。

pounds = newtons/NEWTONS_PER_POUND;

そうではなく、そのポンドが使用時に評価された場合 (cout ステートメントと同様)、ニュートンの値が変更された場合、ポンドの値も変更されます。ポンドはどのタイプのポインターでもなく、単純な整数であるため、これは不可能です。

于 2009-09-01T06:57:09.513 に答える
1

デバッガーでコードをステップ実行するのはどうですか?

IME では、手続き型言語 (つまり、CPU が実際にコードを実行する方法に基づいてモデル化された言語) で記述されたプログラムの実行を理解するのに、このような方法はありません。

于 2009-09-01T08:46:41.993 に答える
0

リスナーにパラダイム シフトを起こさせようとしています。つまり、このコードを理解するためのアプローチ全体を変えようとしています。

「ポンド」は単なる数字です。それがどのように作成されたかについての概念はありません。どのように作成されたかを「ポンド」に伝えても、覚えていません。それがどのように作成されたかではなく、それが何であるかを覚えているだけです。

メモリのブロックを擬人化するのは少し奇妙に思えるかもしれません。:-)

于 2009-09-01T06:56:29.187 に答える
0

newtons変数 likeが再利用され、値が複数回割り当てられている、もう少し複雑な例を見てみましょう。例えば:

double pounds, newtons;

newtons = 10.0;
pounds = newtons/NEWTONS_PER_POUND;
cout << pounds << endl;

newtons = 15.0;
pounds = newtons/NEWTONS_PER_POUND;
cout << pounds << endl;

return 0;

コードと出力の両方を彼に見せてください。次に、プログラムが行ごとに異なる数値を生成する方法と理由を説明するように依頼します。それは、プログラムを上から下に実行される手順として見る方向に彼を後押しするのに役立つはずだと思います.

于 2009-09-02T00:37:35.167 に答える