简体   繁体   中英

How can I return multiple values from a function in c

I don't think that it is important to say what the topic is. I will just mention that I want to print i and a along with the 1 .

Here is my code:

int riz(int k,int *p,int *q)
{
    int i;
    int a;

    for (i = 1; i <= sqrt((double)k) + 1; i++)
    {
        for (a = 1 ; a <= sqrt((double)k) + 1; a++)
        {
            if (a*a+i*i == k)
            {
                p=&a;
                *p=a;
                q=&i;
                *q=i;

                return 1;
            }
        }
    }

    return 0;
}

int main(int argc, char *argv[])
{
    int p;
    int q;
    int a;

    printf("Give me a number or type 0 to exit \n");
    scanf("%d", &a);
    if (a == 0)
        return 0;
    printf("%d\n", riz(a, &p, &q));

    while (a != 0)
    {
        printf("Give me a number or type 0 to exit \n");
        scanf("%d", &a);
        if (a == 0)
            return 0;
        printf("%d\n", riz(a, &p, &q));
    }

    return 0;
}

I've read other questions which are related to this but still I can't figure out why I can't print i and a .

The problem is here:

    if (a*a+i*i==k){
        p=&a;  // p now points to a in riz instead of a in main
        *p=a;  // This is equivalent to a=a
        q=&i;  // q now points to i in riz instead of i in main
        *q=i;  // This is equivalent to i=i

Change to this:

    if (a*a+i*i==k){
        *p=a;  // This will write the value of a in riz to a in main
        *q=i;  // This will write the value of i in riz to i in main

If you want to return multiple values from a function, you have return them through the parameters you pass to the function.

Edit

and you should store the value in *p and not make p point to the address of a .

Here is some explanation.

You are changing what 'p' points to which is 'a' (p = &a) and 'a' goes out of scope at the end of the function. If you were to just make *p = a then that will keep the value that p points at as 'a'.

Same would go for your other variable 'q' so your code would end up with

if (a*a+i*i==k){
        *p=a;
        *q=i;
}

This is because you are making the pointer you passed in the function to point to the variable local to the 'riz' method so when the method 'riz' terminates the variables a and i go out of scope and don't mean anything to your main. So the above code sets the value that 'p' points to the value that 'a' has which is what I assume you want.

At the call site, you need to pass pointers to variables where you want the return values to be placed, which you are doing:

int main(int argc, char *argv[]) {
    int p;
    int q;

    ...

    riz(a,&p,&q)

so far, so good; however, in the function, you simply assign the values you want to return to the locations where the pointers are already pointing. You do not want to change the pointers; the caller already set them to point where they should. This is wrong:

        p=&a;
        *p=a;
        q=&i;
        *q=i;

It should be just:

        *p=a;
        *q=i;

Finally, if you want to print the values after the function returns, you must call the function, and then print the values. Either:

    printf("%d", riz(a,&p,&q));
    printf(" %d %d\n", p, q);

Or, if you want to do it with a single call to printf :

    int r;
    r = riz(a,&p,&q);
    printf("%d %d %d\n", r, p, q);

Do NOT do:

    printf("%d %d %d\n", riz(a,&p,&q), p, q);

because C does not guarantee the order in which parameters are evaluated, so the p and q may be their values before riz is called.

Note however, that when riz returns 0 , p and q will not have been updated, so their values will be garbage (which we blindly print). If this is really the way you want it to work, you probably want to check the return value to decide if you want to do anything with p and q .

On an unrelated note, you have a major code replication issue in main (almost half the code is replicated, which means you have to do twice the work to fix bugs). Why not do:

int main(int argc, char *argv[])
{
    int p;
    int q;
    int a;

    for(;;) {
        printf("Give me a number or type 0 to exit \n");
        scanf("%d", &a);
        if (a == 0)
            break;
        printf("%d\n", riz(a, &p, &q));
    }

    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