调用方未看到函数中的变量更改?

Variable changed in function not seen by caller?

提问人:Alonso Iturbe 提问时间:12/6/2014 最后编辑:M.MAlonso Iturbe 更新时间:12/6/2014 访问量:130

问:

是的,我知道这听起来很傻,但我不知道我做错了什么!

该函数是扑克游戏的一部分,其中有 10 个函数,每个函数检查特定的扑克手牌。如果激活,该函数会打印“玩家 1 有满屋子!”或任何可能的手牌。但是,我还需要增加 p1 的值,其中 p1 是一个全局变量,用于保存 p1 的总分。

打印该行可以完美地工作,但是当我想将 10 的值分配给 p1 时,它根本没有分配。

在下面的示例中,printfs 在应该完美运行的时候工作,但 px 没有分配。我什至在每个函数之后立即打印了 px 的值,它仍然打印 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("\n\nEl Jugador %d tiene un poker de %ss!", j, traducirCarta(c1));
        px = 8;
    }
    if (c5==c2 && c2==c3 && c3==c4)
    {
        printf("\n\nEl Jugador %d tiene un poker de %ss!", j, traducirCarta(c2));
        px = 8;
    }
}
C 变量 按值传递

评论

0赞 phuclv 12/6/2014
stackoverflow.com/questions/10959694/......

答:

4赞 Alex Gidan 12/6/2014 #1

您传递的是“按值”而不是“按引用”的参数。这意味着一旦你传递给函数,你就在函数中拥有了它的副本,因此函数内的任何修改都不会影响原始函数。pxpx

卡莉

尝试一下(请参阅我们现在将参数作为指针传递给函数):

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("\n\nEl Jugador %d tiene un poker de %ss!", j, traducirCarta(c1));
        *px = 8;
    }
    if (c5==c2 && c2==c3 && c3==c4)
    {
        printf("\n\nEl Jugador %d tiene un poker de %ss!", j, traducirCarta(c2));
        *px = 8;
    }
}

访客

这也意味着调用代码的更改。您必须将地址传递给整数,而不是传递整数,例如:

而不是

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

你将不得不做一些事情,如下所示:

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

其他方式

正如 SO 用户 (Charlon) 所建议的那样,您可以选择另一种方法,避免使用指针:您可以用作函数的返回值:px

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("\n\nEl Jugador %d tiene un poker de %ss!", j, traducirCarta(c1));
        px = 8;
    }
    if (c5==c2 && c2==c3 && c3==c4)
    {
        printf("\n\nEl Jugador %d tiene un poker de %ss!", j, traducirCarta(c2));
        px = 8;
    }
    return px;
}

然后你可以像这样分配玩家的得分者:

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

请注意,出于性能原因,我会坚持使用第一种方法(第二种方法中的多余副本)。

延伸阅读

有关该主题的扩展阅读,您可以找到有用的以下链接:[1] [2]

评论

0赞 M.M 12/6/2014
很好的答案,除了关于多余的副本;传递返回值肯定不比传递参数差
0赞 Alex Gidan 12/6/2014
谢谢@MattMcNabb。对于不必要的副本,我的意思是,使用第二种方法,您创建 x,将 x 的副本传递给调用者,将 x 分配给分数持有者,而使用第一种方法,您传递 &x(假设这几乎相当于 1 个 int 副本),但随后您就地修改它,因此它通常应该更高性能......
0赞 zoska 12/8/2014
@AlexGidan 你听说过返回值优化吗?第二个将被优化出来,因此 px 的值将直接放入玩家>scoreholder 中。