K& R练习2-5,错误控制可能达到非空函数c的结束

时间:2016-03-23 21:18:02

标签: c

“编写函数any(s1,s2),它返回字符串s1中字符串s2中任何字符出现的第一个位置,如果s1不包含s2中的字符,则返回-1。 当我编译我的代码时,我得到“控制可能达到非空函数的结束。这部分导致错误,这是我的代码:

int any(string a,string b){
    int i,j;
    int c = 0;
    for(i=0;i<strlen(a);i++){
        for(j=0;j<strlen(b);j++){
            if(b[j]==a[i]&&c==0){
                c = 1;
                return i;
                break;
            }  
        }
    }

    if(c==0) 
    return -1;
}

2 个答案:

答案 0 :(得分:1)

您应该开始学习使用括号,这意味着如果您更改此内容:

if(c==0) 
return -1;

对此:

if(c==0){
    return -1;
}

如果return,您很容易发现没有C != 0

另一个问题是:

if(b[j]==a[i]&&c==0){
    c = 1;
    return i;
    break;
}

首先你说return i;然后是break,真的吗?

另一件事是关于strlen,其定义如下:

size_t strlen(const char * str){
    const char *s;
    for (s = str; *s; ++s) {}
    return(s - str);
}

size_tlong unsigned int,这意味着:

for(i=0;i<strlen(a);i++)

在这里:

for(j=0;j<strlen(b);j++)

您正在将intlong unsigned int进行比较。 这意味着这一行:

int i,j;

应该是:

size_t i,j;

或:

long unsigned i,j;

所以,即使你确定仍然需要一些演员阵容:

int any(string a,string b){
    size_t i,j;
    int c = 0;
    for(i=0;i<strlen(a);i++){
        for(j=0;j<strlen(b);j++){
            if(b[j]==a[i]&&c==0){
                c = 1;
                break;
            }
        }
    }

    if(c==1){
        return (int)i;
    }else{
        return (int)-1;
    }
}

这意味着您应该重新考虑以另一种方式编写整个程序。

也许这对你没问题:

size_t any(string a,string b){
    size_t i,j;
    int c = 0;
    for(i=0;i<strlen(a);i++){
        for(j=0;j<strlen(b);j++){
            if(b[j]==a[i]&&c==0){
                c = 1;
                break;
            }
        }
    }

    if(c==1){
        return i;
    }else{
        return 1;
    }
}

答案 1 :(得分:0)

您收到错误是因为如果您参加测试,编译器不够聪明,无法意识到c == 0必须为true。出于同样的原因,测试完全没必要,因此删除它并在此时返回-1将解决错误。

您可以通过更改为:

来大大简化
int any(char * a, char * b){
    int i, j;

    for( i = 0; a[i]; ++i ) {
        for( j = 0; b[j]; ++j ) {
            if( b[j] == a[i] ) {
                return i;
            }  
        }
    }

    return -1;
}

这避免了冗余测试,完全避免了对c变量的需求,并避免了对strlen()的无偿和重复调用。

typedef char * string b的味道也很差。

可能在本练习的顶部,但通过交换一些内存效率来提高速度效率,您可以将数组设置为查找表并将a中的字符读入其中,然后逐步执行{{ 1}}直到你到达终点或得到一个匹配。这需要遍历b的字符一次,最多遍历a一次完整遍历,这样您就可以获得线性时间算法而不是现在的二次时间算法。

例如:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int any(char * a, char * b);

int main(void)
{
    printf("'rifle', 'flog': %d\n", any("rifle", "flog"));
    printf("'pterodactyl', 'dint': %d\n", any("pterodactyl", "dint"));
    printf("'xyzzy', 'fish': %d\n", any("xyzzy", "fish"));

    return 0;
}

int any(char * a, char * b)
{
    int lookup[CHAR_MAX + 1] = {0};

    for ( int i = 0; b[i]; ++i ) {
        lookup[b[i]] += 1;
    }

    for ( int i = 0; a[i]; ++i ) {
        if ( lookup[a[i]] ) {
            return i;
        }
    }

    return -1;
}

带输出:

paul@horus:~/Documents/src/sandbox$ ./any
'rifle', 'flog': 2
'pterodactyl', 'dint': 1
'xyzzy', 'fish': -1
paul@horus:~/Documents/src/sandbox$