これを解決する最も重要なアイデアは、エラー メッセージを正しく読むことです。以前の質問で、「エラーはオーバーロードされた関数か何かであると言っています」とコメントしました。その態度は、問題を理解するのに役立ちません。エラーメッセージを正しく読む必要があります。
この質問では、エラーについて次のように説明します。
したがって、2 つのエラーは Error: Incompatible types: got "AnsiString" expected "LongInt" This is for Average := Sum / Count; エラー: 互換性のない型: 取得した "バイトのセット" は "Double" である必要があります。このエラーは Temperatures[K] に関するものです:= lstTemp.Items[K];
ただし、説明は、提供されたコードに基づいて表示されるはずのエラーに対応していません。
エラーを読んでおらず、誤って正しいことをしてしまうことを期待してやみくもに変更を加え始めたようです。エラーを読まなかったので、エラーが変更されたことに気づきませんでした。そのため、ヘルプを求めて私たちに来たとき、古いエラーに新しいコードを提供したり、その逆を行ったりしました。
エラー メッセージを実際に正しく読んでいれば、問題を自分で解決できたかもしれません。少なくとも、コードと実際に一致する説明を使用して、より適切な質問をすることができたはずです。
平均 := 合計 / カウント;
Average
、Sum
およびCount
すべてとして宣言されていInteger
ます。表示されるはずのエラー メッセージは、「互換性のない型: IntegerおよびExtended」です。
エラー メッセージを読めば、とを読む手がかりが得られるはずです。Integer
Extended
ここでの問題は、数学では除算によって有理数が生成されることです。それに対応して、プログラム内の除算演算の結果は整数ではありません。Average
したがって、またはのいずれかDouble
として宣言する必要がありますExtended
。
温度[K] := lstTemp.Items[K];
Temperatures
の配列として宣言されInteger
ます。の宣言は示されていませんがlstTemp
、他のコードに基づいて、それItems
は として宣言された標準の Delphi コントロールの 1 つですTStrings
。したがって、表示されるエラー メッセージは次のとおりです。「互換性のない型:整数と文字列」。
エラー メッセージを読めば、5 行前に行ったのと同じことを行う手がかりが得られるはずです。
このエラーの理由は、Delphi が「強く型付けされた」言語であるためです。コンパイラは、特定の種類の間違いを犯さないようにしようとします。lstTemp
の値の 1 つがである場合に何が起こるか想像してみてください'Hello'
。これは整数に変換できません。プログラムで「実行時」エラーが発生します。
この問題を解決するには、コンパイラに次のように伝える必要があります。これを行うには、関数を呼び出しStrToInt
ます。注: 無効な文字列が関数に渡された場合でも実行時エラーが発生しますが、明示的に変換を行うことを強制することで、入力データの事前検証を行うかどうかを検討できます。
コンパイラによって報告されたエラーについて質問しました。これは、プログラミング中に直面するエラーの 1 種類に過ぎず、通常は最も簡単に解決できます。また、ロジック エラーが発生することもあります。つまり、プログラムは正常にコンパイルされますが、正しく動作しません。Andreas の優れた回答は既にそれらをカバーしているので、繰り返しません。
しかし、私はあなたにいくつかの貴重なアドバイスをします。コンパイラ エラーを解決するというハードルを乗り越え、簡単に解決できるようになったら、できるだけ早く次のことを行う必要があります。
- コードを徹底的にテストする習慣を身につけてください。
- 統合デバッガーの使用方法を学習します。
- その制限について学びます。
- ロギング、プロファイリング、事前および事後条件チェックなど、その他のデバッグ手法を学びます。
最後に、Min、Max、Sum、または Avg を取得するための単純な関数がないというalcalde の暴言への応答として、別の可能な実装を提供します。
基本的に、暴言は、彼がむしろ次の行に沿って何かを書きたいという事実についてのものでした:
begin
if (lstTemp.Count > 0) then
begin
edtMin.Text := lstTemp.Min;
edtMax.Text := lstTemp.Max;
edtAvg.Text := lstTemp.Average;
end
else
begin
ShowMessage('List is empty');
end;
end;
明らかに上記のコードはコンパイルできませんが、少し手を加えるだけで同様のことが実現できます。
彼は次の 2 つの点で完全に正しいです。(1)この実装はよりクリーンで、保守がはるかに簡単で、エラーの可能性が少ないということです。(2) Delphi は、単純にそれを行う方法を提供していません。
実際、トップダウンの設計アプローチに従う場合、これが最初の疑似コードになる可能性があります。返金を要求しないのであれば、トップダウンの設計について教えられるべきです。:)トップダウン設計アプローチの背後にある要点は、理想的な実装
を探しているということです。何があるか、何がないかを気にする必要はありません。現在のライブラリとツールが機能を提供しない場合は、独自の.Min
あなたはプログラマーです。あなたには力があります。
私はこれを「希望的観測プログラミング」と呼ぶことがあります。他のものが整っていれば、「これ」のように機能をもっと簡単に実装できるといいのですが。それからあなたはあなたの願いをかなえることに取り掛かります。
これ以上苦労することなく、これが実装です。Math ユニットを使用する必要があります。
type
{ We will call existing functions that take TDoubleArray as input }
TDoubleArray = array of Double;
TStringsHelper = class(TStrings)
{ A useful class to help us convert TStrings into TDoubleArray }
public
class function Using(AStrings: TStrings): TStringsHelper;
function AsDoubleArray: TDoubleArray;
end;
{ TStringsHelper }
function TStringsHelper.AsDoubleArray: TDoubleArray;
var
LoopI: Integer;
begin
SetLength(Result, Count);
for LoopI := 0 to Count - 1 do
begin
Result[LoopI] := StrToFloat(Strings[LoopI]);
end;
end;
class function TStringsHelper.Using(AStrings: TStrings): TStringsHelper;
begin
Result := TStringsHelper(AStrings);
end;
var
LTemperatures: TDoubleArray;
begin
{ This code is almost the same as our "ideal" implementation }
if (lstTemp.Items.Count > 0) then
begin
LTemperatures := TStringsHelper.Using(lstTemp.Items).AsDoubleArray;
edtMin.Text := FloatToStr(MinValue(LTemperatures));
edtMin.Text := FloatToStr(MaxValue(LTemperatures));
edtMin.Text := FloatToStr(Mean(LTemperatures));
end
else
begin
ShowMessage('List is empty');
end;
end;