Từ 1 tới 3 trên tổng số 3 kết quả

Đề tài: Toán tử và Con trỏ C++

  1. #1
    Ngày gia nhập
    06 2007
    Bài viết
    0

    Mặc định Toán tử và Con trỏ C++

    Toán tử .* dc dùng trong những trường hợp nào vậy?em k hiểu rõ lắm!
    Con trỏ this nữa,em cug k biết rõ là nó dủng trong những trường hợp nào hết
    Mấy anh chị giúp em nha!

  2. #2
    Ngày gia nhập
    07 2006
    Nơi ở
    Hanoi, Vietnam
    Bài viết
    2,750

    Trước khi trả lời cho cậu, Dr muốn hỏi cậu: Cậu đã đọc sách và tài liệu về lập trình C++ chưa? Nếu có, cậu đã đọc những cuốn sách nào hay tài liệu nào?
    Email: admin[@]congdongcviet.com | CC to: info[@]congdongcviet.com
    Phone: 0972 89 7667 (Office: 04 6329 2380)
    Yahoo & Skype: dreaminess_world (Vui lòng chỉ rõ mục đích ngay khi liên hệ, cảm ơn!)

    Một người nào đó coi thường ý thức kỷ luật cũng có nghĩa là người đó đã coi thường tương lai số phận của chính bản thân người đó. Những người coi thường ý thức kỷ luật sẽ không bao giờ có được sự thành công trong sự nghiệp!

  3. #3
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Cái này mình đọc được từ sách và dịch lại, nhưng nó chỉ là những phần cơ bản nhất thôi. Về con trỏ và đối tượng + cấp phát động thì còn rất nhiều. Bạn có thể đọc sách : "How to program C++ của Deitel " viết khá đầy đủ, hoặc sách "Object oriented của Robert Lafore ( cuốn này đc đánh giá rất và rất hay).

    Using Pointers
    Cách hiệu đơn giản nhất đối với định nghĩa về con trỏ là : con trỏ là 1 biến chứa địa chỉ. Tuy hiểu thì đơn giản nhưng dùng được nó lại rất phức tạp. Nhưng chúng ta cứ đi từng bước nắm rõ bản chất thì có lẽ mọi thứ cũng ok.!!!
    Địa chỉ của vùng nhớ mà con trỏ lưu trữ là địa chỉ của 1 biến khác vì thế ta nói “con trỏ” trỏ tới biến đó. Cú pháp khai báo nó như sau :
    Code:
    type* pointer_name;
    Đầu tiên bản phải học 1 toán tử mới là toán tử địa chỉ “&”. Chúng ta sẽ đặt nó trực tiếp đằng trước 1 biến mang ý nghĩa là nó được coi địa chỉ của vùng nhớ đó. Xét ví dụ sau :
    Code:
    int my_var;
    int* a_pointer = &my_var;
    Đoạn code trên nói răng con trỏ “a_pointer” trỏ tới my_var. Chú ý là nếu 1 con trỏ được gán giá trị 0 thì con trỏ đó không phải đang trỏ tới 1 biến. Trường hợp này gọi là “null pointer” hoặc con trỏ chưa được khai báo. Nhìn tiếp vào ví dụ sau :
    PHP Code:
    #include <iostream>
    using namespace std;
    int main(void)
    {
          
    int my_var 5;
          
    inta_pointer = & my_var;
          
    cout << "The value of my_var is: " << my_var
              
    << "\nThe address of my_var is: " << &my_var
              
    << "\nThe value of a_pointer is " << a_pointer
              
    << "\nThe address of a_pointer is: " << &a_pointer
              
    << "\nThe value of my_var or *a_pointer " << *a_pointer
              
    << "\n\n Show that * and & are inverse of each other :"
              
    << "\n&*a_pointer is : " << &*a_pointer
              
    << "\n*&a_pointer is : " << *&a_pointer;


    Hãy đọc tới đọc lui ví dụ trên để chắc rằng bạn hiểu nó, trước khi đi vào phần kế tiếp.
    Using Pointers and Objects
    Chúng ta cũng có thể dùng con trỏ để trỏ đến đối tượng hay cấu trúc. Ví dụ, chúng ta có thể dùng con trỏ để trỏ tới đối tượng Point như sau :
    Code:
    Point* ps
    Bạn thấy đó, những con trỏ kiểu này thì giống y chang những kiểu con trỏ khác. Tuy nhiên chúng ta cần chú ý 1 số điểm sau. Đầu tiên, không có đối tượng nào thực sự được tạo ra, chỉ có con trỏ đến nó thôi. Và cũng bởi vì lý do này, chúng ta không thực sự đang gọi constructor của class “string” ( C++ chỉ gọi constructor khi nào chúng ta khai báo một “Point” bởi vì “Point” là 1 class, không phải loại dữ liệu thông thường. Thứ 2 nếu chúng ta có 1 lớp Point như sau :
    PHP Code:
    class Point{
    public:
         
    int X,Y;
         
    Point (int lXint lY) : X(lX), Y(lY){}
         
    void print();
    };
    void Point::print()
    {
         
    cout << "The value of X is: " << X
              
    << "/nThe value of Y is: " << << endl;

    Và ta có thể tạo ra 1 đối tượng từ lớp đó như sau :
    Code:
    Point p(5,3);
    Tiếp đến chúng ta có thể tạo 1 con trỏ, trỏ đến đói tượng này :
    Code:
    Point* pp = &p;
    Chúng ta có thể truy xuất đến thành viên của đối tượng này bằng cách dùng con trỏ như sau :
    Code:
    pp->X = 6;
    pp->Y = 5;
    Và chúng ta cũng có thể dùng nó để gọi hàm thành viên như sau :
    Code:
    pp->print();
    [Trích trừ sách C++ programming for absolute beginner]
    Using the this Pointer
    Mỗi đối tượng của 1 lớp có 1 con trỏ constant ( con trỏ hằng ) trỏ đến chính nó ( gọi là this pointer ). Với con trỏ này chúng ta có thể truy xuất đến bất kì dữ liệu thành viên nào có thuộc tính public hoặc là hàm thành viên của lớp đó. Cú pháp cho con trỏ hằng như sau. Ví dụ, trong lớp Point ở trên, ta có thể viết lại hàm print() dùng con trỏ hằng :
    Chú ý là không được dùng con trỏ hàng cho hàm thành viên có thuộc tính “static”. Xem ví dụ sau :
    Code:
    void Point::print()
    {
         cout << "The value of X is: " << this->X
              << "/nThe value of Y is: " << this->Y << endl;
    }
    Sự thay đổi này sẽ chẳng làm thay đổi gì tới ý nghĩa của phương thức, mà đơn giản là nó chỉ là 1 cách rõ ràng để chỉ ra instance nào của class đang ám chỉ tới. Vậy chúng ta cũng có thể dùng this pointer để lấy đối tượng như sau :
    Point p = *this;
    Thông tin này có vẻ chẳng có tác dụng gì vào lúc này, nhưng nó sẽ trong tương lai.

    [Trích trừ sách How to program C++ ]
    Using the this Pointer

    Chúng ta có thể thấy rằng hàm thành viên có thể taho tác trên dữ liện của đối tượng. Vậy câu hỏi đặt ra là làm sao hàm thành viên biết dữ liệu thành viên của đối tượng nào cần được thao tác?
    Mỗi đối tượng có quyền truy xuất đến địa chỉ của chính nó bằng 1 con trỏ “this” ( từ khóa của C++). Con trỏ this của đối tượng không phải là 1 phần của đối tượng đó, nghĩa là kíck cỡ của vùng nhớ cung cấp cho con trỏ this không ảnh hưởng đến kết quả sự hoạt động của “sizeof” trên đối tượng đó. Con trỏ this được truyền vào đối tượng ( bởi trình biên dịch ) như là 1 đối số ngầm định cho mỗi lần hàm thành viên không có thuộc tính static gọi nó.
    Đối tượng dùng con trỏ this 1 cách ngầm định hoặc rõ ràng để tham chiếu đến dữ liệu thành viên và hàm thành viên của nó. Kiểu của con trỏ this phụ thuộc vào kiểu của đối tượng và nó cũng phụ thuộc vào hàm thành viên được dùng và khai báo là const. Ví dụ, 1 hàm thành viên được khai báo non-const của lớp class Employee, con trỏ hằng có kiểu Employee *const ( con trỏ const trỏ tới đối tượng non-const ). Trong khi đó đối với hàm thành viên được khai báo const của lớp Employee, thì con trỏ hằng có kiểu dữ liệu là const Employee *const ( con trỏ constant trỏ tới đối tuợng const ).
    Mỗi hàm thành viên có thuộc tính non-static đều có quyền được truy xuất đến con trỏ this – con trỏ trỏ tới đối tượng mà hàm thành viên đang được triệu gọi.
    Implicitly and Explicitly Using this Pointer access an Object’s Data members:
    Đoạn code dưới đây sẽ mô tả cách dùng ngầm định và rõ ràng đối với con trỏ this.
    Hàm thành viên print() đầu tiên xuất ra kết quả của x bằng cách dùng con trỏ 1 cách ngầm định ( chỉ có tên của dữ liệu thành viên là cụ thể ). Sau đó là việc dùng con trỏ this theo 2 cách : “->” và “.”. Chú ý rằng cái ngoặc đóng mở xung quanh *this khi dùng với toán tử “.”. Dấu ngoặc này là bắt buộc vì toán tử “.” có độ ưu tiên cao hơn toán tử “*”. Không có nó, câu lệnh sẽ được hiểu là *this.x và nó sẽ dẫn đến lỗi cú pháp vì toán tử “.” Không được dùng với con trỏ.
    Một điều thú vị của việc sử dụng con trỏ this là để tránh việc đối tượng tự gán cho chính nó. Vấn đề này sẽ được thảo luận chi tiết khi ta học về đối tượng có chứa con trỏ và cấp phát động.
    Xem ví dụ sau đây về cách dùng con trỏ để áp dụng “cascaded”:
    PHP Code:
    #include <iostream>
    using std::cout;
    using std::endl;

    #include <iomanip>
    using std::setw;
    using std::setfill;


    class 
    Time
    {
          public :
                
    Time int 0int 0int );
                
    Time &setTime intintint );
                
    Time &setHour ( int );
                
    Time &setMinute ( int );
                
    Time &setSecond ( int );
          
                
    int getHour() const;
                
    int getMinute() const;
                
    int getSecond() const;
          
                
    void printUniversal() const;
                
    void printStandard() const;
          private :
                
    int hour;
                
    int minute;
                
    int second;
    };

    Time::Time int hint mint s )
    {
          
    setTime hm);
    }

    Time &Time::setTime int hint mint s )
    {
          
    setHour );
          
    setMinute );
          
    setSecond );

          return *
    this/*Enable cascading*/
    }

    Time &Time::setHourint h )
    {
          
    hour = ( >= && 24 ) ? ;
          return *
    this/*Enable cascading*/
    }

    Time &Time::setMinute int m )
    {
          
    minute = ( >= && 60 ) ? 0;
          return *
    this;
    }

    Time &Time::setSecondint s )
    {
          
    second = ( >= && 60 ) ? 0;
          return *
    this/*Enable cascading*/
    }

    int Time::getHour() const
    {
          return 
    hour;
    }

    int Time::getMinute() const
    {
          return 
    minute;
    }

    int Time::getSecond() const
    {
          return 
    second;
    }

    void Time::printUniversal() const
    {
          
    cout << setfill ('0') << setw(2) << hour << ":"
               
    << setw(2) << minute << ":"
               
    << setw(2) << second;
    }

    void Time::printStandard() const
    {
          
    cout << ( ( hour == || hour == 12 ) ? 12 hour 12 )
               << 
    ":" << setfill('0') << setw(2) << minute
               
    << ":" << setw(2) << second
               
    << ( hour 12 "AM" "PM" );
    }

    int main(void)
    {
          
    Time Obj;
          
          
    /*Cascaded function calls*/
          
    Obj.setHour(18).setMinute(30).setSecond(22);

          
    cout << "\nUniversal time :";
          
    Obj.printUniversal();
          
          
    cout << "\nStandard time : ";
          
    Obj.printStandard();

          
    cout << "\n\nNew standard time ";

          
    Obj.setTime 202020 ).printStandard();
          
          
    cout << endl;
         
          
    system("pause");
          return 
    0;

    Chương trình sau tạo ra 1 đối tượng Obj, và sau đó dùng kĩ thuật cascaded gọi hàm. Vậy tại sao trả về *this là 1 tham chiếu lại thực hiện được điều này? Chú ý toán tử “.” được tính từ trái qua phải, vì vậy dòng lệnh : “Obj.setHour(18) trả về 1 tham chiếu đến đối tượng đến đối tượng Obj như là 1 giá trị của hàm này. Tức là phần còn lại có thể hiểu là :
    Obj.setMinute(30).setSecond(12);
    Tương tự lời gọi Obj.setMinute(3) trả về 1 tham chiếu đến đối tượng Obj, phần còn lại được hiểu là Obj.Second(22);
    Dòng lệnh gần cuối : Obj.setTime (20,20,20 ).printStandard(); cũng dùng kĩ thuật cascading. Lời gọi hàm phải được đặt theo thứ tự như trên bởi vì hàm printStandard() được định nghĩa trong class không trả về 1 tham chiếu đến Obj. Đặt printStandard trước setTime là 1 lỗi cú pháp.

    Đọc toàn lý thuyết không chắc là oải lắm phải không ^^ ! Mình sẽ cho bạn 1 loạt ví dụ để nghiên cứu, bạn hãy cố ngẫm xem nó chạy thế nào nhé :
    Example 1
    Pointer to Object
    PHP Code:
    #include <iostream>

    using namespace std;

    class 
    SimpleCat
    {
          public : 
                
    /*Constructor*/
                
    SimpleCat int ageint weight );
               ~
    SimpleCat() {}
                
                
    int getAge() 
                {
                      return 
    itsAge;
                }
                
                
    int getWeight() 
                {
                      return 
    itsWeight;
                }
          
          private :
                
    int itsAge;
                
    int itsWeight;
    };

    SimpleCat::SimpleCat int ageint weight )
          :
                
    itsAge (age), itsWeight (weight)
    {}

    SimpleCat &Function();

    int main()
    {
          
    SimpleCat &rCat = Function();
          
          
    int age rCat.getAge();
          
    cout << " rCat is " << age << endl;
          
          
    cout << " &rCat is : " << &rCat << endl;
          
          
    /*How do we get rid of memory*/
          
    SimpleCat *pCat = &rCat;
          
    delete pCat;

          
    int tcin >> t;
          return 
    0;
    }

    SimpleCat &Function()
    {
          
    SimpleCat *pFrisky = new SimpleCat (4,9);
          
    cout << "pFrisky : " << pFrisky << endl;
          return *
    pFrisky;

    Example 2
    Pointer point to the same memory bug
    Ví dụ này khá hay bạn chịu khó đọc kĩ 1 tí và cố hiểu nó nhé :
    PHP Code:
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    class 
    sample 
    {
          
    char *s;
          public:
                
    sample() { 0; }
                
    sample(const sample &ob); // copy constructor
                
    ~sample( ) 
                { 
                      if(
    sdelete [] s
                      
    cout << "Freeing s\n"
                }
                
    void show() 
                {   
                      
    cout << << "\n"
                }

                
    void set(char *str);
    };
    // Copy constructor.
    sample::sample(const sample &ob)
    {
          
    = new char[strlen(ob.s)+1];
          
    strcpy(sob.s);
    }
    // Load a string.
    void sample::set(char *str)
    {
          
    = new char[strlen(str)+1];
          
    strcpy(sstr);
    }
    // Return an object of type sample.
    sample input()
    {
          
    char instr[80];
          
    sample str;
          
    cout << "Enter a string: ";
          
    cin >> instr;
          
    str.set(instr);
          
          return 
    str;
    }
    int main()
    {
          
    sample ob;
          
    // assign returned object to ob
          
    ob input(); // This causes an error!!!!
          
    ob.show();
          return 
    0;

    Nhớ lại xem khi mà một hàm trả về một đối tượng, nó cũng đồng thời sẽ tạo ra 1 đối tượng tạm thời đẻ dữ lại giá trị đó. Bởi vì copy constructor sẽ cấp phát động cho nó 1 vùng nhớ khi bản sao được tạo ra. Đối tượng gốc “s” và đối tượng s trong bản copy sẽ trỏ tới những vùng nhớ khác nhau điều này làm cho chúng là hoàn toàn độc lập. Tuy nhiên lỗi vẫn xảy ra vì khi đối tượng được trả về thì nó được gán cho “ob” bởi vì theo mặc định thì phép gán thể hiện 1 bản sao kiểu “bitwise” ( srry mình cũng chẳng biết dịch chỗ này sao nữa, bạn cố hiểu nó nhé ). Trong trường hợp này, đố tượng tạm thời sẽ trả về bởi lời gọi hàm input() và nó được copy vào “ob”. Và điều này dẫn đến ob.s trỏ đến cùng 1 vùng nhớ với đối tượng tạm thời đó. Tuy nhiên, sau khi phép gán được thực hiên, vùng nhớ lại được giải phóng cũng là lúc đối tượng tạm thời đc hủy bỏ. Vì vậy, ob.s đang trỏ tới vùng nhớ đã được giải phóng ( rỗng ) !!!! Hơn nữa, khi chương trình kết thúc, thằng ob.s lại 1 lần nữa được giải phóng, và điều này sẽ làm cho vùng nhớ lại được giải phóng 1 lần nữa. Để tránh điều này, chúng ta phải quá tải toán tử gán sao cho đối tượng sẽ nằm bên trái của phép gán và cấp phát cho nó 1 vùng nhớ riêng biệt.
    Và đây là cách fix nó :
    Example 2(cont.)
    Fix bug
    PHP Code:
    // This program is now fixed.
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    class 
    sample 
    {
          
    char *s;
          public:
                
    sample(); // normal constructor
                
    sample(const sample &ob); // copy constructor
                
    ~sample( ) 
                { 
                      if(
    s
                            
    delete [] s
                      
    cout << "Freeing s\n"
                }
                
    void show() 
                { 
                      
    cout << << "\n"
                }
                
    void set(char *str);

                
    sample operator=(sample &ob); // overload assignment
    };
    // Normal constructor.
    sample::sample()
    {
          
    = new char('\0'); // s points to a null string.
    }
    // Copy constructor.
    sample::sample(const sample &ob)
    {
          
    = new char[strlen(ob.s)+1];
          
    strcpy(sob.s);
    }
    // Load a string.
    void sample::set(char *str)
    {
          
    = new char[strlen(str)+1];
          
    strcpy(sstr);
    }
    // Overload assignment operator.
    sample sample::operator=(sample &ob)
    {
    /* If the target memory is not large enough
    then allocate new memory. */
          
    if(strlen(ob.s) > strlen(s)) 
          {
                
    delete [] s;
                
    = new char[strlen(ob.s)+1];
          }
          
    strcpy(sob.s);

          return *
    this;
    }
    // Return an object of type sample.
    sample input()
    {
          
    char instr[80];
          
    sample str;

          
    cout << "Enter a string: ";
          
    cin >> instr;
          
    str.set(instr);

          return 
    str;
    }
    int main()
    {
          
    sample ob;
          
    // assign returned object to ob
          
    ob input(); // This is now OK
          
    ob.show();

          return 
    0;

    Lỡ tới đây rồi thì bạn chắc đã có khái niệm sơ sơ về con trỏ và đối tượng rồi phải không nào , lỡ rồi thì chơi thêm luôn ví dụ này ^^ nhé !
    Example 3
    Reference vs Pointer

    PHP Code:
    /*REFERENCE VERSION*/
    #include <iostream>
    using namespace std;
    class 
    Distance                    // English Distance class
    {
          private:
                
    int feet;
                
    float inches;
          public:
                
    void getdist()              // get length from user
                
    {
                      
    cout << "\nnEnter feet: ";  cin >> feet;
                      
    cout << "\nEnter inches: ";  cin >> inches;
                }
          
    void showdist()             // display distance
          

                
    cout << feet << "\n’-" << inches << "\n"
          }
    };
    ////////////////////////////////////////////////////////////////
    int main()
    {
          
    Distancedist = *(new Distance);  // create Distance object
                              // alias is “dist”
          
    dist.getdist();                    // access object members
          
    dist.showdist();                   //    with dot operator
          
    cout << endl;
       
          return 
    0;
    }

    /*POINTER VERSION*/
    #include <iostream>
    using namespace std;
    class 
    Distance              //English Distance class
    {
          private:
                
    int feet;
                
    float inches;
          public:
                
    void getdist()        //get length from user
                
    {
                      
    cout << "\nEnter feet: ";  cin >> feet;
                      
    cout << "\nEnter inches: ";  cin >> inches;
                }
          
                
    void showdist()       //display distance
                

                      
    cout << feet << "\n’-" << inches << "\n"
                }
    };
    ////////////////////////////////////////////////////////////////
    int main()
    {
          
    Distance dist;           //define a named Distance object
          
    dist.getdist();          //access object members
          
    dist.showdist();         //   with dot operator

          
    Distancedistptr;       //pointer to Distance
          
    distptr = new Distance;  //points to new Distance object
          
    distptr->getdist();      //access object members
          
    distptr->showdist();     //   with -> operator
          
    cout << endl;
       
          return 
    0;

    Bây h là code thực sự nè ^^ ! Nói đùa vậy chứ nó cũng rất đơn giản nhưng nó luyện cho mình hiểu hơn về cách hoạt động của con trỏ và đối tượng. Bạn hãy cố nghiền ngẫm nó nhé :
    Example 4
    GAME TICTACTOE

    PHP Code:
    #include <iostream>
    #include <string>
    using namespace std;      //introduces namespace std

    enum SquareState {blank ' ''X''O'};

    class 
    gameBoard
    {
        private:     
              const 
    int WIDTH;
              const 
    int HEIGHT;
              
    intGameBoard;
        public:
              
    gameBoard() : WIDTH(3), HEIGHT(3)
              {
                    
    GameBoard = new int[9];
                    for (
    int i 09i++)
                          *(
    GameBoard i) = blank;
              }
             ~
    gameBoard() {delete[] GameBoard;}
             
    void setX(int hint w);
             
    void setO(int hint w);
             
    bool isTaken(int hint w);
             
    SquareState isLine(); 
             
    void draw();
    };
    void gameBoard::setX(int hint w)
    {
          *(
    GameBoard h*HEIGHT w) = X;
    }
    void gameBoard::setO(int hint w)
    {
          *(
    GameBoard h*HEIGHT w) = O;
    }
    bool gameBoard::isTaken (int hint w)
    {
          return *(
    GameBoard h*HEIGHT w) != ' ';
    }
    SquareState gameBoard::isLine()
    {
          if(*
    GameBoard==&& *(GameBoard +1)==&& *(GameBoard +2)==X)
                return 
    X;
          if(*
    GameBoard==&& *(GameBoard +1)==&& *(GameBoard +2)==O)
                return 
    O;
          if(*(
    GameBoard +3)==&& *(GameBoard +4)==&& *(GameBoard +5)==X)
                return 
    X;
          if(*(
    GameBoard +3)==&& *(GameBoard +4)==&& *(GameBoard +5)==O)
                return 
    O;
          if(*(
    GameBoard +6)==&& *(GameBoard +7)==&& *(GameBoard +8)==X)
                return 
    X;
          if(*(
    GameBoard +6)==&& *(GameBoard +7)==&& *(GameBoard +8)==O)
                return 
    O;
         
          if(*
    GameBoard==&& *(GameBoard +3)==&& *(GameBoard +6)==X)
                return 
    X;
          if(*
    GameBoard==&& *(GameBoard +3)==&& *(GameBoard +6)==O)
                return 
    O;
          if(*(
    GameBoard +1)==&& *(GameBoard +4)==&& *(GameBoard +7)==X)
                return 
    X;
          if(*(
    GameBoard +1)==&& *(GameBoard +4)==&& *(GameBoard +7)==O)
                return 
    O;
          if(*(
    GameBoard +2)==&& *(GameBoard +5)==&& *(GameBoard +8)==X)
                return 
    X;
          if(*(
    GameBoard +2)==&& *(GameBoard +5)==&& *(GameBoard +8)==O)
                return 
    O;
         
          if(*
    GameBoard==&& *(GameBoard +4)==&& *(GameBoard +8)==X)
                return 
    X;
          if(*
    GameBoard==&& *(GameBoard +4)==&& *(GameBoard +8)==O)
                return 
    O;
          if(*(
    GameBoard +2)==&& *(GameBoard +4)==&& *(GameBoard +6)==X)
                return 
    X;
          if(*(
    GameBoard +2)==&& *(GameBoard +4)==&& *(GameBoard +6)==O)
                return 
    O;
         
          return 
    blank;
    }


    void gameBoard::draw()
    {
          
    cout << endl;
          for(
    int i=0HEIGHTi++)
          {
                
    cout << (char)*(GameBoard i*HEIGHT);
                for(
    int c=1WIDTHc++)
                      
    cout << " | " << (char)*(GameBoard i*WIDTH c);
                      
    cout << endl << "______" << endl
          }
    }
    class 
    Game
    {
          public:
                
    gameBoarddoInput(string playergameBoardgb);
                
    bool inRange(int test);
    };

    gameBoardGame::doInput(string playergameBoardgb)
    {
          
    gb->draw();
          
    string letter;
          if (
    player.compare("I") == 0)
                
    letter "X";
          else if (
    player.compare("II") == 0)
                
    letter "O";
          else return 
    gb;
          
    int input1input2;
          do 
          {
                do 
                {
                      
    cout << "\nPlayer " << player.c_str()
                           << 
    ", please enter a row number to put an "
                           
    << letter.c_str() << ": ";
                      
    cin >> input1;
                } 
                while(!
    inRange(input1));
              
                do 
                {
                      
    cout << "\nPlease enter a column number to put an " 
                           
    << letter.c_str() << ": ";
                      
    cin >> input2;
                } 
                while(!
    inRange(input2));
          
          } 
          while (
    gb->isTaken(input1,input2));
         
          if (
    player.compare("one") == 0)
                
    gb->setX(input1input2);
          else 
    gb->setO(input1input2);
                return 
    gb;
    }

    bool Game::inRange(int test)
    {
         return 
    test > -&& test 3;
    }
    int mainvoid )
    {
          
    gameBoardgb = new gameBoard;
          
    Game g;
          
    string player1player2;
          
    cout << "\nWelcome to Tic Tac Toe!"
               
    << "\nPlayer I, please enter your name: ";
          
    cin >> player1;
          
    cout << "\nPlayer II, please enter your name: ";
          
    cin >> player2;
         
          while (
    gb->isLine() == ' ')
          {
                
    gb g.doInput("I",gb);
                
    gb g.doInput("II",gb);
          }
         
          
    gb->draw();
          
          if(
    gb->isLine() == X)
                
    cout << "\nPlayer one, you win!"
                     
    << "\nGame Over.";
          else 
                
    cout << "\nPlayer two, you win!"
                     
    << "\nGame Over.";
         
          return 
    0;

    Thân !

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn