none
《C#入门经典》第十章关于扑克牌的程序 怎么也看不懂 RRS feed

  • 問題

  • using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Ch10CardLib
    {
        public enum Suit
        {
            Club,
            Diamond,
            Heart,
            Spade,
        }
        public enum Rank
        {
            Ace = 1,
            Deuce,
            Three,
            Four,
            Five,
            Six,
            Seven,
            Eight,
            Nine,
            Ten,
            Jack,
            Queen,
            King,
        }
        public class Card
        {
            public readonly Suit suit;
            public readonly Rank rank;

            public  Card(Suit newSuit,Rank newRank)
            {
                this.suit = newSuit;
                this.rank = newRank;
            }

            private Card() { }

            public override string ToString()
            {
                return "The " + rank + " of " + suit + "s";
            }
        }
      public class Deck
      {
        private Card[] cards;  //声明类数组

        public Deck()
        {
          cards = new Card[52];  //创建52个对象
          for (int suitVal = 0; suitVal < 4; suitVal++)
          {
            for (int rankVal = 1; rankVal < 14; rankVal++)
            {
              cards[suitVal * 13 + rankVal - 1] = new Card((Suit)suitVal,(Rank)rankVal); //实例化52个对象,并且通过构造函数给suit和rank赋值,问题来了。。类不是引用类型的吗,这样赋值suit和rank不是都是一样的吗?
            }
          }
        }

        public Card GetCard(int cardNum)  //这里声明的这个方法是干什么的啊??不太明白。
        {
          if (cardNum >= 0 && cardNum <= 51)
            return cards[cardNum ];  //这里是返回对象里的ToString方法里的内容吗,因为类是引用类型的,这里只代表了cards[cardNum]的指针,返回的结果不都是一样的吗?怎么都不理解!!!
          else
            throw (new System.ArgumentOutOfRangeException("cardNum", cardNum, "数字在0-51间"));
        }

        public void Shuffle()
        {
          Card[] newDeck = new Card[52]; //声明了52个类数组
          bool[] assigned=new bool[52]; //声明了52个bool类型的变量
          Random sourceGen = new Random();  //实例化一个随机数对象
          for (int i = 0; i < 52; i++)
          {
            int destCard = 0;
            bool foundCard = false; //声明一个bool变量为假
            while (foundCard == false) //如果为假就循环
            {
              destCard = sourceGen.Next(52); //赋一个1-52之间的随机数给destCard
              if (assigned[destCard] == false) //前面都没给assigned赋值,这里怎么就出现了个如果为假执行下面的代码那???
                foundCard = true; //等于真,跳出循环
            }
            assigned[destCard] = true;
            newDeck[destCard] = cards[i];
          }
          newDeck.CopyTo(cards ,0);
        }
      }
    }

    本人属于业余爱好者,可能基础东西搞的不是很清楚,但是真心的喜欢编程,望各位高手多多帮助,谢谢了

     

    2011年1月9日 下午 05:03

解答

  • 你好,

    关于你的第一个问题:例化52个对象,并且通过构造函数给suit和rank赋值,问题来了。。类不是引用类型的吗,这样赋值suit和rank不是都是一样的吗?

    suit和rank是不一样的,suit表示花色,急我们所说的黑桃啊,方片之类的,而rank才真正表示牌的大小,如A,2,3,4等。

    第二个问题:这里是返回对象里的ToString方法里的内容吗,因为类是引用类型的,这里只代表了cards[cardNum]的指针,返回的结果不都是一样的吗?怎么都不理解!!!
    这里返回的是Card类对象,它的返回类型定义的是Card,怎么可能返回string类型呢。

    第三个问题:前面都没给assigned赋值,这里怎么就出现了个如果为假执行下面的代码那???

    对于bool类型的数组,它已经被实例化了,只是没有一个个去赋值,这时未赋值的所有成员默认的为false,这个你可以自己去试试。

    最后,你的这个问题没有涉及到任何sharepoint相关东西,请以后注意发帖的时候发在相应的板块。


    Microsoft Online Community Support
    • 已標示為解答 KeFang Chen 2011年1月14日 上午 08:38
    2011年1月10日 上午 02:13

所有回覆

  • 你好,

    关于你的第一个问题:例化52个对象,并且通过构造函数给suit和rank赋值,问题来了。。类不是引用类型的吗,这样赋值suit和rank不是都是一样的吗?

    suit和rank是不一样的,suit表示花色,急我们所说的黑桃啊,方片之类的,而rank才真正表示牌的大小,如A,2,3,4等。

    第二个问题:这里是返回对象里的ToString方法里的内容吗,因为类是引用类型的,这里只代表了cards[cardNum]的指针,返回的结果不都是一样的吗?怎么都不理解!!!
    这里返回的是Card类对象,它的返回类型定义的是Card,怎么可能返回string类型呢。

    第三个问题:前面都没给assigned赋值,这里怎么就出现了个如果为假执行下面的代码那???

    对于bool类型的数组,它已经被实例化了,只是没有一个个去赋值,这时未赋值的所有成员默认的为false,这个你可以自己去试试。

    最后,你的这个问题没有涉及到任何sharepoint相关东西,请以后注意发帖的时候发在相应的板块。


    Microsoft Online Community Support
    • 已標示為解答 KeFang Chen 2011年1月14日 上午 08:38
    2011年1月10日 上午 02:13
  •  您好,

             版主,谢谢你的讲解,我是第一次在这里面发表问题,板块不对下次不会在发错了,呵呵

             1;不过我的第一个问题你好像理解错了,我的意思是,类数组是怎么存储的啊? cards[suitVal * 13 + rankVal - 1] = new Card((Suit)suitVal,(Rank)rankVal); 这里的cards[suitVal * 13 + rankVal - 1]是52个指针,指针同时都指向Card类,Card类不管有什么变化这52个对象都指向Card类,这段代码我就不明白了,要是照这样循环下去的话不就成了:cards的这0—51个指针不同时都指向Card((Suit)3,(Rank)13),这怎么对那?我该怎么理解这句话那?

             2;这里返回的是Card类对象,它的返回类型定义的是Card,怎么可能返回string类型呢。这句话能不能举个例子啊?呵呵,我运行程序后,发现return出来的就是ToSring里的内容啊?而且自己也做了个小例子,证明就是ToSring在发挥作用啊?

             非常渴望得到答案,真是麻烦你们了,谢谢了

    2011年1月10日 上午 05:09
  • 你好,

    52个指针不是指向Card类,而是指向Card的实例。类的确是引用类型,但不是指你说的定义的这个类,而是指的类的实例。

    在定义这个数组的时候,运行时会自动计算52个card以及其它一些东西计算分配内存;

    举个例子来说,指向这个数组的指针就相当于是一个小区的门牌号码,小区里面的每栋楼还有一个编号,这个编号就相当于这个card数组中指向每个card的指针。

    关于你说的ToString的问题,你是怎么输出的?

    如果是用类似Console.WriteLine(Object o)这种方式输出,即直接把一个object用来作为输出参数的的话,它是自动调用ToString()方法的。

    如果你不重写ToString方法,它会调用基类Object的ToString按如下方式输出:

    return this.GetType().ToString();

    而上面的ToString最终按如下输出:

    "Type: " + objtype.Name

     


    Microsoft Online Community Support
    2011年1月10日 上午 05:36
  • 您好!

             对于值类型存储 在栈中,引用类型存储在堆中我是理解的,但当一个类中的成员字段本身也是引用类型时,数据是怎样存储我我搞不清楚了。还有,对于一个结构体中,成员字段是怎样存储也搞不清楚。例如:

    情况一:
    class A{}
    class B
    {
    private A a;  //问题1)对于这个字段到底是存储在堆中还是栈中?
    public void Test(){}   //问题2) 对于这个成员方法是怎么存储的呢?
    }

    情况二:

    struct JGT
    {
      A a;//问题3::A是前面定义的类,照理说结构体是值类型,应该存储在栈中,但是它这个成员字段是引用类型,应该存储在哪呢???
    }

    情况一中.的A也是存储在堆上的.
    栈上指向堆上B的指针->B(这个在堆上),然后B中有个指针指向堆中A所在的地址

    情况二中.JGT被分配在栈上.同样内部有个指向堆中A所在内存的指针.

    问题四::对于一般定义的函数或者类或者结构体中的成员方法在内存中是怎么存储的??
    问题五::对于类中的静态变量或者静态方法,存储的方式是怎样的??

    问题六:类数组是怎么存储的啊?比如:cards[suitVal * 13 + rankVal - 1] = new Card((Suit)suitVal,(Rank)rankVal);

     

    2011年1月11日 下午 02:53
  • 你好,

    讨论值类型和引用类型,下面是一个很好的文章。

    http://apps.hi.baidu.com/share/detail/278453

    对不起,一个帖子最好只讨论一个问题。

    你后面的问题可以重新开帖,发到相应的论坛。


    Microsoft Online Community Support
    2011年1月12日 上午 01:53
  • 真是太谢谢您了,呵呵,我的问题解决了

    2011年1月12日 上午 02:59