Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
285 views
in Technique[技术] by (71.8m points)

c - Variable changed in function not seen by caller?

Yes, I know it sounds silly but i have no idea what i'm doing wrong!

The function is part of a poker game, in which there are 10 functions, each which checks for a specific poker hand. If activated, the function prints the line "Player 1 has a full house!" or whatever the hand might be. But, i also need to increment the value of p1, in which p1 is a global variable the holds the total score for p1.

Printing the line works perfectly, but when i want to assign, for example, a value of 10 to p1, it simply doesn't assign.

In the example below, the printfs work perfectly when they should, but the px's don't assign. I've even printed the value for px immediately after each function and it still prints 0s.

void checkForPoker(int j, int px) //j is the player's number, px is the player's scoreholder
{
    if ((c1==c2 && c2==c3 && c3==c4) || (c1==c2 && c2==c3 && c3==c5) || (c1==c2 && c2==c4 && c4==c5) || (c1==c3 && c3==c4 && c4==c5))
    {
        printf("

El Jugador %d tiene un poker de %ss!", j, traducirCarta(c1));
        px = 8;
    }
    if (c5==c2 && c2==c3 && c3==c4)
    {
        printf("

El Jugador %d tiene un poker de %ss!", j, traducirCarta(c2));
        px = 8;
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're passing the parameter "by value" and not "by reference". This means that once you pass px to the function you have a copy of it inside the function, so any modification inside the function won't affect the original px.

Callee

Try with this (see we are now passing to the function the parameter as a pointer):

void checkForPoker(int j, int* px) //j is the player's number, px is the player's scoreholder
{
    if ((c1==c2 && c2==c3 && c3==c4) || (c1==c2 && c2==c3 && c3==c5) || (c1==c2 && c2==c4 && c4==c5) || (c1==c3 && c3==c4 && c4==c5))
    {
        printf("

El Jugador %d tiene un poker de %ss!", j, traducirCarta(c1));
        *px = 8;
    }
    if (c5==c2 && c2==c3 && c3==c4)
    {
        printf("

El Jugador %d tiene un poker de %ss!", j, traducirCarta(c2));
        *px = 8;
    }
}

Caller

This implies also a change in the calling code. Instead of passing the integer you will have to pass the address to the integer, something like:

Instead of

int a = 2;
checkForPoker(2, a);

You will have to do something like:

int a = 2;
checkForPoker(2, &a);

Alternative Way

As suggested by a SO user (Charlon) you could choose another approach, avoiding the use of pointers: you can use px as return value of the function:

int checkForPoker(int j) //j is the player's number
{
    int px = 0;
    if ((c1==c2 && c2==c3 && c3==c4) || (c1==c2 && c2==c3 && c3==c5) || (c1==c2 && c2==c4 && c4==c5) || (c1==c3 && c3==c4 && c4==c5))
    {
        printf("

El Jugador %d tiene un poker de %ss!", j, traducirCarta(c1));
        px = 8;
    }
    if (c5==c2 && c2==c3 && c3==c4)
    {
        printf("

El Jugador %d tiene un poker de %ss!", j, traducirCarta(c2));
        px = 8;
    }
    return px;
}

And then you could assign player's scoreholder like this:

player->scoreholder = checkForPoker(int j) //j is the player's number

Please note that I'd stick to the first approach for performance reasons (superfluous copies in the second approach).

Further Readings

For an extended reading on the subject you could find useful these links: [1] [2]


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...