K & R Exercises 2-5

"Write a function any (s1, s2) that returns the first place in string s1 where any character from string s2 occurs, or -1 if s1 contains no characters from s2. (The strpbrk standard function does the same job, but returns pointer to location. "

I am wondering if it would be a bad habit to cast the return statement in a loop instead of using "char_match = YES" as I am doing here:

#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;
}

      

How about returning the i-1? This is bad? Should I find another way to do this?

+3


source to share


4 answers


To answer your questions:

  • Having multiple return statements is ok.
  • As a potential return statement: return i-1;

    great.

So, you can rewrite this code like this:

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;
}

      

Or, how could I write something like this:



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;
}

      

Which I think is much more readable.

Generally, when you implement a search function, I think that having an expression in the loop return

should be the preferred notation .

Also, while I know this is a learning exercise, it's worth noting that there is a very similar function called in string.h strpbrk()

that would do almost all the work for you.

+4


source


The only reason multiple statements return

can be bad is if you need to do any cleanup before exiting the function. For example, if you are allocating memory for multiple pointers in your particular function, then you will need to make sure that you free them all before these assertions. In your particular case, having it return

inside the loop is fine as you won't be dealing with any memory management.



+2


source


There are no reliable anders as to whether it is better to use multiple returns or not, however keep in mind that - if you take a multiple return path - you need to think about freeing resources (FILE handle, malloc, etc.), since you are not have any facility in C like you do in another language (C ++, Java, etc.).

Here's your code using multiple returns and where I return i

instead i - 1

(which is ok because it ++i

was executed just before the end of the ^ loop).

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;
}

      

It is wrong to use multiple return, you should always use {} to delimit blocks (eg "else if"). And you should really avoid multiple variable initialization, for example i = j = 0

.

0


source


There is no need to continue looping after you find the answer. Return

is the best choice in your case.

0


source







All Articles