[解決済み] 修正方法 - コントロールが非ボイド関数の終わりに達する可能性があります。
2022-02-17 17:07:16
質問事項
cs50の授業で、バイナリサーチ関数を書かなければならない問題が発生しました。
コードを実行しようとすると、このようなメッセージが表示されます。
control may reach end of non-void function
. 私は最後の行を追加することによって修正しようとしました
return false
が、これでは出力が常に
false
. 何かヒントがあれば教えてください。
以下は私のコードです。
bool search_r(int value, int values[], int l, int r) {
int v = values[(l + r) / 2];
int right = r;
int left = l;
if ((l + r) / 2 > 0) {
if (v == value) {
return true;
} else
if (v > value) {
right = ((l + r) / 2);
search_r(value, values, left, right);
} else
if (v < value) {
left = ((l + r) / 2);
search_r(value, values, left, right);
}
} else {
return false;
}
}
解決方法は?
この関数にはいくつかの問題があります。
-
を再帰的に呼び出したときの値を返す必要があります。
search_r()
. このエラーは、関数にreturn
文の後に、ネストされたif
ステートメントを使用します。それを作ることreturn false;
を返すべきであり、最後に書くのは正しくありません。true
もしvalue
が見つかりました。 -
(l + r) / 2
はオーバーフローする可能性があります。l
またはr
が非常に大きい場合。この場合、結果は正しくないでしょう。正しい中間インデックスの計算方法は次の通りです。l + (r - l) / 2
. -
終了のためのテストは
(l + r) / 2 > 0
であるかどうかだけをテストします。> 0
. 代わりにl < r
つまり、範囲が空でない場合です。l
が含まれr
を除く。 -
テストの様子
if (v < value)
は冗長であり、すでにv == value
とv > value
. -
使用方法
l
と視覚的に非常に似ているため、変数名として使用するとやや混乱します。1
特にコードに使用される固定ピッチのフォントの場合。
以下は修正版です。
bool search_r(int value, int values[], int left, int right) {
if (left < right) {
int middle = left + (right - left) / 2;
int v = values[middle];
if (v == value) {
return true;
} else
if (v > value) {
return search_r(value, values, left, middle);
} else {
return search_r(value, values, middle + 1, right);
}
} else {
return false;
}
}
最後に、この関数は再帰を使用する代わりにループとして実装することもできます。 再帰は終端なので、コンパイラは同じコードを生成する可能性が高いが、人によっては一方の方法の方が直感的だと感じることもある。
bool search_r(int value, int values[], int left, int right) {
while (left < right) {
int middle = left + (right - left) / 2;
int v = values[middle];
if (v == value) {
return true;
} else
if (v > value) {
right = middle;
} else {
left = middle + 1;
}
}
return false;
}
どちらの場合も、このように関数を呼び出す必要があります。
length
の要素数です。
array
.
bool found = search_r(value, array, 0, length);
関連
-
[解決済み] (.text+0x20): `main'への未定義の参照と関数への未定義の参照
-
[解決済み】Cygwin - Makefile-error: ターゲット `main.o' のレシピに失敗しました。
-
[解決済み】 switch case: error: case label does not reduce to an integer constant
-
[解決済み】LEALアセンブリ命令は何をするのですか?
-
[解決済み] [Solved] なぜこのようなエラーが発生するのでしょうか。「データ定義に型またはストレージクラスがない」?
-
[解決済み】MB/sとMiB/sを計算する方法は?
-
[解決済み] C: エラー: ';'トークンの前に ')' があると予想される
-
[解決済み】未定義参照 makefile が間違っているのかも?
-
[解決済み] エラー: `itoa` はこのスコープで宣言されていません。
-
[解決済み】C言語の関数ポインタはどのように機能するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン