表示适合整数的数据类型

Mos*_*erd 1 c++ data-representation

似乎有两种方法可以用C++表示卡片.

显而易见的方式是:

const int numCards = 52;
const int numRanks = 13;
const int numSuits = 4;

enum Suit {
    HEARTS  = 1;
    DIAMOND = 2;
    SPADES  = 3;
    CLUBS   = 4;
}

card Class {
    private:
        const Suit suit;
        const int rank;

    public:
        /// Constructor
        Card(int rank, Suit suit)

        /// Get rank between 1 and 13
        int getRank();

        /// Get suit
        Suit getSuit();

        /// Get string representation
        std::string toString();
};
Run Code Online (Sandbox Code Playgroud)

还有另一种方法,整个卡由一个字节表示.

namespace Cards {
    typedef byte Card;

    /// Constructor
    Card getCard(int rank, Suit suit); // return (rank - 1) + numRanks * (suit - 1);

    /// Validity check
    boolean isValid(Card);

    /// Get a rank between 1 and 13
    int getRank(Card); // return 1 + (card % numRanks);

    /// Get suit
    Suit getSuit(Card); // return 1 + (card // numSuits)

    /// Get string representation
    std::string toString(Card);
};
typedef Cards::Card Card;
Run Code Online (Sandbox Code Playgroud)

第一个似乎更明显,优点是卡有自己的类型.这使它更安全,因为它不能与另一种类型混淆.另一方面,第二表示是存储器有效的并且使得一些操作相对容易.例如,创建一个套牌可以通过

void initializeDeck(Card[] deck) {
    // Pre: sizeof(deck) >= 52!!!

    // No need to iterate over both rank and suit!!!
    for(Card card = 0; card < numCards; card++) {
        deck[card] = card;
    }
}
Run Code Online (Sandbox Code Playgroud)

我还应该使用第一种方式还是有办法获得两者的优势?

GWW*_*GWW 5

另一种选择是使用位域.

struct Card {
    unsigned char suit:2;
    unsigned char rank:6;
};
Run Code Online (Sandbox Code Playgroud)

然后,您可以像任何其他成员变量一样访问组件.

Card card;
card.suit = HEARTS;
card.rank = 5;
Run Code Online (Sandbox Code Playgroud)

您还可以添加其他方法Cardstruct来添加字符串序列化等内容.

作为一个快速说明,我会从0-3编号你的西装,所以它们可以适合2位而不是3位.

  • 作为参考,这被称为[位字段](http://en.cppreference.com/w/cpp/language/bit_field). (2认同)