【问题标题】:Swapping algorithm giving everything the same value交换算法赋予一切相同的价值
【发布时间】:2015-10-26 17:34:33
【问题描述】:

我的课程任务是编写一个程序,该程序创建 52 个卡片对象,每张卡片都有一个价值和一套花色。在我们创建了一个对象数组之后,我们必须随机切换两张牌的位置。问题是当我去交换我的卡时,它们都变成了相同的。这是导致问题的代码:

void SwapCards(Card* cardOne, Card* cardTwo) {
    //swap cards here
    Card *temp = cardOne;
    *cardOne = *cardTwo;
    *cardTwo = *temp;
    //once it gets here all three variables end up with the same object?
}

现在是调用这个函数的 for 循环:

for (int i = 0; i < 104; i++) { 
    //get two random values and send them to SwapCards to switch both objects
    int c_one = RandomRange(0, 51);
    int c_two = RandomRange(0, 51);
    SwapCards(deck[c_one], deck[c_two]);
}

对此的任何帮助将不胜感激。我花了很多时间试图弄清楚,但这让我非常困惑。

【问题讨论】:

  • 如果你想要引用(和值temp),请避免使用指针
  • deck的类型是什么?
  • @AnonMail 他实际上是在取消引用 cardTwo 并将其分配给取消引用的 cardOne。问题是 temp 不是卡的副本,而是指针。
  • 然后查看cplusplus.com/reference/algorithm/swap - 将引用传递给您希望交换的项目而不是指针会更常见。
  • std::swap 是核心构建块。不幸的是,许多人从来没有时间教这些东西。

标签: c++ pointers swap


【解决方案1】:

“问题是当我去交换我的卡时,它们都变成了相同的。”

您在这里失去了cardOne 的当前值:

*cardOne = *cardTwo;

由于temp 仍指向与cardOne 相同的地址,因此cardOne 的原始值并未与其一起保存。

如下修改你的代码,保存cardOne的值:

Card temp = *cardOne;
*cardOne = *cardTwo;
*cardTwo = temp;

更好(并且可能更清晰)的解决方案是使用引用而不是指针:

void SwapCards(Card& cardOne, Card& cardTwo) {
    //swap cards here
    Card temp = cardOne;
    cardOne = cardTwo;
    cardTwo = temp;
}

附带说明:std::swap() 已经这样做了,无需在此处推出您自己的实现。

【讨论】:

    【解决方案2】:

    Card *temp = cardOne; 中的temp 中删除*。而是使用

    Card temp = *cardOne;
    

    然后

    *cardTwo = temp;
    

    【讨论】:

    • 只需等待几分钟即可!
    • @NathanOliver 好的。对不起。会修改的。
    • @NathanOliver 我认为在这种情况下可以:因为 Temunish 说“非常感谢”,我们可以假设他接受了这个作为答案,并且因为他是 SO 新手(从他的代表),可以假设他要么忘记接受它,要么根本不接受答案。我看到很多带有“谢谢”消息的好答案,但没有被接受(即使这是该问题的唯一答案)。
    • @Satus 嘿,你从来没有接受过答案。如果这个答案你可能想接受它没关系。原来的评论基本上没问题。接受这个答案。
    • @Temunish Well 另一个帮助吸血鬼 OP 的示例,接受第一个让他们的代码工作的答案,而不关心任何解释,或者可能改进的地方。叹息!
    【解决方案3】:

    在 C++ 中编写“交换”函数的标准方法是传递 引用 而不是指针:

    void swap(Card &a, Card &b)
    {
        Card tmp(a);  // or Card tmp = a;
        a = b;
        b = tmp;
    }
    

    没有必要调用函数swapCard,因为参数匹配意味着它只能用两个Card 参数调用。

    然后可以使用模板使其几乎完全通用:

    template <class T> void swap ( T& a, T& b )
    {
        T tmp(a);  // construct a copy of a
        a = b;     // overwrite 'a'
        b = c;     // replace 'b' with the copy
    }
    

    这是一种常见的范例,以至于它成为标准 - std::swap

    如果T 类型兼容,它“就可以工作”,否则您可以为特定类实现模板的“特化”。有时出于有效的原因需要专门化(例如,您可以交换成员指针而不是复制其内容)。

    【讨论】:

    • 我同意,但这是一项家庭作业,我认为指针是作业的一部分。
    【解决方案4】:

    进入函数时,cardOne指向一张卡片,cardTwo指向另一张卡片。

     Card *temp = cardOne;
    

    temp 现在指向cardOne指向的卡片。

     *cardOne = *cardTwo;
    

    cardOne 指向的卡现在与cardTwo 指向的卡具有相同的值。

     *cardTwo = *temp;
    

    cardTwo 指向的卡现在与temp 指向的卡具有相同的价值,这与cardOne 指向的卡相同——你刚刚给的卡与卡相同的价值cardTwo 指向。
    换句话说,这将分配给*cardTwo 的值与*cardTwo 已有的值相同。

    对于交换,您要保存*cardTwo 的值,而不是其地址。

    Card temp = *cardOne;
    *cardOne = *cardTwo;
    *cardTwo = temp;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多