K& R练习2-5

时间:2014-08-13 22:14:19

标签: c

"写函数any(s1,s2),它返回字符串s1中字符串s2中出现任何字符的第一个位置,如果s1不包含s2中的字符,则返回-1。 (标准库函数strpbrk执行相同的工作但返回指向该位置的指针。"

我想知道在循环中放置一个return语句而不是使用" char_match = YES"这是一个坏习惯。正如我在这里做的那样:

#define YES 1
#define NO 0
int char_seek(char string[], char string2[])
{
    int i, j;
    int char_match = NO;

    for (i = j = 0; string[i] != '\0' && char_match == NO; ++i){
        while (string2[j] != '\0' && string[i] != string2[j])
            ++j;
        if (string2[j] == '\0')
            j = 0;
        else if (string[i] == string2[j])
            char_match = YES;
    }
    if (char_match == NO)
        return -1;
    else
        return i-1;
}

返回i-1怎么样?那不好吗?我应该找到一种不同的方法吗?

3 个答案:

答案 0 :(得分:4)

回答你的问题:

  1. 有多个return语句就好了。
  2. 作为潜在的退货声明:return i-1;没问题。
  3. 所以你当然可以将代码重写为:

    int char_seek(char string[], char string2[])
    {
        int i, j;
    
        for (i = j = 0; string[i] != '\0'; ++i){
            while (string2[j] != '\0' && string[i] != string2[j])
                ++j;
            if (string2[j] == '\0')
                j = 0;
            else if (string[i] == string2[j])
                return i;
        }
    
        return -1;
    }
    

    或者,我可能会写这样的东西:

    int char_seek(const char *string, const char *string2) {
        for (int i = 0; string[i] != '\0'; ++i)
            for (int j = 0; string2[j] != '\0'; ++j)
                if (string[i] == string[j])
                    return i;
        return -1;
    }
    

    我认为这更具可读性。

    作为一般规则,当您实施搜索功能时,我认为在循环中包含return语句应为首选表示法。

    另外,虽然我知道这是一个学习练习,但值得注意的是string.h中有一个非常类似的函数,名为strpbrk(),几乎可以完成所有的工作。

答案 1 :(得分:2)

多个return语句的唯一原因可能是坏的,如果你需要在退出函数之前进行任何类型的清理。例如,如果为特定函数中的多个指针分配内存,则需要确保在这些语句之前释放所有指针。在您的特定情况下,在循环中使用return是完全正常的,因为您不会与任何内存管理相冲突。

答案 2 :(得分:0)

没有有效的anwsers关于它是否更好地使用多个返回,但请记住 - 如果你采用多个返回路径 - 你必须考虑资源释放(FILE句柄,malloc等),因为你不像你有其他语言(C ++,Java等)在C中有任何设施。

您的代码使用多次返回,我返回i而不是i - 1(这是正常的,因为++i在循环结束之前执行了^)

int char_seek(char string[], char string2[])
{
    int j = 0;
    for (int i = 0; string[i] != '\0'; ++i) {
        while (string2[j] != '\0' && string[i] != string2[j]) {
            ++j;
        }
        if (string2[j] == '\0') {
            j = 0;
        } else if (string[i] == string2[j]) {
            return i;
        }
    }
    return -1;
}

虽然使用多次返回并没有错,但您应该始终使用{}来分隔块(例如"否则如果")。你应该真的避免像i = j = 0这样的多变量初始化。