是'否则如果'这个函数多余了?

时间:2016-05-02 19:41:17

标签: c if-statement return control-flow

因此,使用C程序中的以下函数来确定数字是素数还是复数:

/** 
 * Determine if a given integer is prime. O(sqrt n).
 * n: The integer to examine.
 * return: TRUE if n is prime; FALSE if n is not prime.
 */
BOOL APIENTRY IsPrime(int n)
{
    int i;
    double test;
    if(n <= 1) return FALSE;
    else if(n <= 3) return TRUE; // Is the else keyword at beginning of this line useful?

    for(i = 2; i <= sqrt(n); i++)
    {
        test = (double) n / (double) i;
        if (test == floor(test)) return FALSE;
    }
    return TRUE;
}

如果我用if (n <= 3) return TRUE;替换第12行,该函数仍然可以正常工作(因为前一个if语句捕获n不是素数的情况,前提是它是1,0或负数)。我是否应该保留else关键字?

5 个答案:

答案 0 :(得分:2)

if(n <= 1) return FALSE;
else if(n <= 3) return TRUE;

if(n <= 1) return FALSE;
if(n <= 3) return TRUE;

是相同的,因为return FALSE;结束当前函数的执行(与任何return语句一样)。所以生成的汇编代码应该是相同的,你可以保留或不作为你看起来更可读的东西。

答案 1 :(得分:2)

如果您的编译器足够智能,那么在else之前,编译的代码将与if相同或不同。

但是,在你的代码中,你写道:

for (...; n<= sqrt(n); ...)

可能(它再次依赖于编译器)在每次循环迭代时调用sqrt函数。

替换为:

int limit = sqrt(n);
for (i = 3; i <= limit; i +=2)
    ...

答案 2 :(得分:2)

是的,无条件返回<?php namespace App\Http\Requests; use Response; use Illuminate\Foundation\Http\FormRequest; class UploadRequest extends FormRequest { public function rules() { $request = $this->instance()->all(); $images = $request['files']; $rules = [ 'files' => 'required' ]; foreach($images as $key => $file) { $rules['files.'.$key] = 'image|mimes:jpeg,png,gif'; } return $rules; } public function messages() { $request = $this->instance()->all(); $images = $request['files']; $messages = [ 'files.required' => 'You must upload a file.' ]; foreach($images as $key => $file) { $messages['files.'.$key.'.image'] = 'The upload file must be an image.'; $messages['files.'.$key.'.mimes'] = 'The image must be one of the following types: JPEG, PNG, or GIF.'; } return $messages; } public function authorize() { return true; } public function response(array $errors) { $request = $this->instance()->all(); $images = $request['files']; $image = $images[0]; $error_string = ''; foreach($errors['files.0'] as $error) { $error_string.= ' '.$error; } $json = array('files' => array( array( 'name' => $image->getClientOriginalName(), "size" => $image->getClientSize(), 'error' => $error_string ) )); return Response::json($json); } } 分支后的else总是多余的:

if

达到&#34;更多代码的唯一方法&#34;行是if (someCondition) { ... do something, then return someValue; } // <<== An "else" here would be redundant ... more code 评估为someCondition,这与到达false分支的条件相同。

else分支与其他类型的无条件转移控制相同,例如ifbreak。存在代码分析工具以警告程序员冗余。

答案 3 :(得分:1)

由您决定,真的

此外,i从2开始,所以是的,你可以丢弃它。

偏离主题:为什么使用浮点运算?你想找到素数。您可能会遇到问题,请注意!

答案 4 :(得分:1)

在这种情况下,由于您从代码返回,因此无关紧要。在这两种情况下,无论如何,编译后的代码都会在if (n <= 3)时跳转到n > 1

这是因为如果第一个if语句为false,则必须始终评估第二个条件。在两个函数的汇编输出中都可以很容易地看到(并且应该总是直接验证):

Ltmp7:
    cmpl    $2, %edi
    jge LBB0_2
    xorl    %eax, %eax
    jmp LBB0_8 // jump to return false
LBB0_2:
    movb    $1, %r14b
    cmpl    $4, %edi
    jl  LBB0_3 // jump to return true

VS

Ltmp15:
    cmpl    $2, %edi
    jge LBB1_2
    xorl    %eax, %eax
    jmp LBB1_8 // jump to return false
LBB1_2:
    movb    $1, %r14b
    cmpl    $4, %edi
    jl  LBB1_3 // jump to return true

通过将代码修改为类似

来给出一个有趣的转折
if (n <= 3) return n > 1;

因为现在你只有一个分支,所以可以进行不同的优化,例如在我的编译器(clang-3.4)上产生

cmpl    $4, %edi
jge LBB0_1 // jump to function body
cmpl    $1, %edi
setg    %al
jmp LBB0_7 // jump to return with $al register already set

使用setg指令根据之前的比较直接设置返回值。