简体   繁体   中英

Pass string by reference recursively in C

The desired output is:

orange 1
apple 2
apple 3

Instead, I get this:

orange 1
apple 2
orange 3

when I executed my code:

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

void change(char *word) {        // passing pointer to subroutine
    if (word != "apple") {       // WARNING FROM COMPILER
        printf("%s 1\n", word);  // value state #1
        word = "apple";          // change "orange" to "apple"
        change(word);            // recursion happens here
    } else
        printf("%s 2\n", word);  // value state #2
}

int main() {
    char word[] = "orange";

    change(word);                // pass string by reference
    printf("%s 3\n", word);      // value state #3 

    return 0;
}

the gcc compiler I'm using gives me the following warning:

comparison with string literal results in unspecified behavior [-Waddress] at line 5:

if (word != "apple") {         // WARNING FROM COMPILER

I have tried so many ways but still failed to make a proper pass-by-reference from main() to change() as indicated in #3 state print. It should work recursively too.

Could you spot any problems with my code?

You can't compare string using the equality or inequality operators, it will compare the pointers word and the one the array "apple" decays to.

Also, you can't use the assignment operator in the code, as that will assign to the local pointer variable word inside the function only.

To solve the first problem, use strcmp instead, and for the second use strcpy . But be careful when using strcpy so you don't copy a to long string that writes beyond the end of the original array.

The != reference does not work. You need to use strcmp() for comparison.

Similarly, changing the contents of the buffer requires strcpy() .

Additionally, the size of the buffer would not be correct as "apple" creates a buffer of 6 characters (to include the ending '\0' NULL character). "orange" requires a buffer of size 7, so you will have a buffer overflow problem as well if the initial word is smaller than orange (though your example code does set it to orange).

You should make your buffer big enough to fit the largest size needed for your words and call strlen() to check the size of the new word against the known maximum buffer size assuming that you want a more general case and not just "apple" and "orange" in your change function.

Once you fix these problems properly, you should see better results.

Try these changes:

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

void change(char *word){         //passing pointer to subroutine
    if(!strcmp(word,"apple")){         //returns 0 when strings are equal
        printf("%s 1\n", word);  //value state #1
        strcpy(word,"apple");          //change "orange" to "apple"
        change(word);            //recursion happens here
    }
    else printf("%s 2\n", word); //value state #2
}

int main(){
    char word[] = "orange";

    change(word);                //pass string by reference
    printf("%s 3\n", word);      //value state #3 

    return 0;
}

strcmp() description here

First: Please respect the warning. Don't do comparison of String literals.

But, coming to the point of why you are not getting your expected result, the reason is that though you are passing a pointer, you are passing it by value. So, even though you think you are assigning a new address to the variable word, the same doesn't reflect back in your caller function.

Solution

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

void change(char *word) {         
    if (strcmp(word, "apple")) {        
        printf("%s 1\n", word);  
        strcpy(word, "apple");          
        change(word);            
    } else
        printf("%s 2\n", word);  // value state #2
}

int main() {
    char word[20]; 

    strcpy(word, "orange");
    change(word);                // pass string by reference
    printf("%s 3\n", word);      // value state #3 

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM