if与else if的区别及非void函数编译错误问题咨询
二分查找编译错误分析:非void函数未在所有路径返回值
编写的C语言二分查找代码编译时出现错误提示:non-void function does not return a value in all control paths [-Werror,-Wreturn-type]。明明所有if语句都设置了返回值却报错,对比参考答案用else if的写法正常运行,想搞清楚错误原因以及if和else if的区别。
原代码
#include <cs50.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <math.h> int binary(int a[],int target,int l,int r); //return index , needs array, target left index, right index //goal: find if the number is in the array int main(void) { int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13}; int target = get_int("number:"); int l = 0; int r = 13; int index=binary(a,target,l,r); if(index>=0) printf("number %i is at index %i\n",target,index); else printf("not found\n"); } int binary(int a[],int target,int l,int r) { if(r<l) { return -1; } int mid=l+(r-l)/2; if(a[mid]==target) { return mid; } if(a[mid]<target) { return binary(a,target,mid+1,r); } if(a[mid]>target) { return binary(a,target,l,mid-1); } }
错误信息
non-void function does not return a value in all control paths [-Werror,-Wreturn-type]
问题原因
从逻辑上看,a[mid]与target的关系只有等于、小于、大于三种,最后两个if必然会触发一个,但编译器的静态分析不会做这么深入的逻辑推导。它只会把三个if看作独立的分支:虽然每个分支里都有return,但编译器认为存在“所有if都不满足”的可能性(哪怕逻辑上不可能),此时函数会走到末尾没有返回值,因此抛出错误。
if与else if的核心区别
- 独立if:多个
if是并行的判断逻辑,每个if都会被依次检查(除非前面的if里有return直接退出)。编译器会默认这些分支是独立的,存在全部不命中的可能。 - else if:属于链式条件判断,是同一分支结构的一部分。当前面的if/else if不满足时,才会检查下一个else if。编译器能识别出这些分支是互斥的,配合逻辑覆盖的话,会判定函数必然会进入某一个分支并返回值。
修改后的正确代码
把最后两个独立的if改成else if,让编译器识别出这是覆盖所有剩余情况的链式判断:
#include <cs50.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <math.h> int binary(int a[],int target,int l,int r); //return index , needs array, target left index, right index //goal: find if the number is in the array int main(void) { int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13}; int target = get_int("number:"); int l = 0; int r = 13; int index=binary(a,target,l,r); if(index>=0) printf("number %i is at index %i\n",target,index); else printf("not found\n"); } int binary(int a[],int target,int l,int r) { if(r<l) { return -1; } int mid=l+(r-l)/2; if(a[mid]==target) { return mid; } else if(a[mid]<target) { return binary(a,target,mid+1,r); } else // 这里也可以用else if(a[mid]>target),用else更简洁 { return binary(a,target,l,mid-1); } }
内容的提问来源于stack exchange,提问作者chunwai
相关产品推荐
相关产品推荐

