调用者看不到函数中的变量更改?

Posted

技术标签:

【中文标题】调用者看不到函数中的变量更改?【英文标题】:Variable changed in function not seen by caller? 【发布时间】:2015-02-03 21:07:12 【问题描述】:

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

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

打印线效果很好,但是当我想为 p1 分配例如 10 的值时,它根本不分配。

在下面的示例中,printfs 在应有的情况下完美地工作,但 px 没有分配。我什至在每个函数之后立即打印了 px 的值,它仍然打印 0。

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;
    

【问题讨论】:

***.com/questions/10959694/… 【参考方案1】:

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

被调用者

试试这个(看看我们现在将参数作为指针传递给函数):

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]

【讨论】:

很好的答案,除了关于多余的副本;传返回值肯定不比传参数差 感谢@MattMcNabb。我对不必要副本的意思是,在第二种方法中,您创建 x将 x 的副本传递给调用者将 x 分配给 scoreholder ,而使用第一种方法时,您 pass &x (假设这几乎相当于 1 个 int 副本),但随后您就地对其进行了修改,因此它通常应该具有更高的性能... @AlexGidan 你听说过返回值优化吗?第二个会被优化出来,所以px的值会直接放到player->scoreholder中。

以上是关于调用者看不到函数中的变量更改?的主要内容,如果未能解决你的问题,请参考以下文章

方法如何访问调用者的属性?

C#知识点整理

为啥函数可以修改调用者感知的某些参数,而不能修改其他参数?

请大家解释一下Delphi的回调函数

为啥包装在函数中的 GAS 内联汇编为调用者生成的指令与纯汇编函数不同

了解 Alloc 的 Instruments 结果中的负责任调用者