Announcement

Collapse
No announcement yet.

Xin giúp đỡ về toán tử x++

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [C++] Xin giúp đỡ về toán tử x++

    Sau một hồi tranh luận nảy lửa giữa mìn và bạn vẫn chưa có câu trả lời đúng cho trường hợp mình đã gặp phải thế này
    mình dùng g++ 4.6 (GNU) và bạn mình dùng C-Free C++ 4.6 luôn
    bài như sau
    #include<iostream>
    int main()
    {
    int c;
    std::cin>>c;
    c=(c+++2);
    std::cout<<c;
    std::cout<<c;

    return 0;
    }
    khi chạy trên hai máy khác nhau c=3 kết quả ra khác nhau: mình ra 4 4 bạn mình ra 5 5
    chư hết nếu thay cin >> c bằng c=3 thì hai kết quả hoàn toàn giống nhau là 6
    mình muốn hỏi vì sao có sự khác biệt này
    Be different and always different
    http://archlinuxvn.org/
    http://theslinux.org
    http://lab.infosec.xyz

  • #2
    Mình kết luận là máy 2 bạn có vấn đề
    Mình dùng GNU C++ và Visual Studio 2010 cả 4 trường hợp GNU cin, GNU c=3, VS cin và VS c=3 tất cả đều ra 66

    Nói giỡn thôi chứ chưa thấy toán tử +++ bao giờ, hình như bạn xài HĐH Linux phải ko ? Mình xài Win7, Mình đã thử test server linux và nó ra 4 4 nếu cin
    Last edited by 09520019; 31-10-2011, 23:26.
    Khoảng cách giữa bạn và ước mơ của bạn là bao xa ?

    Comment


    • #3
      dạ đúng đó anh ra 4 nếu cin và 6 nếu c=3
      nhưng sự khác biệt ở đây là gì ah
      toán tử C+++2 do 2 là hằng số nên nó tính c++ r62i cộng với 2 nhưng sao hai cái khác nhau quá
      nếu cout<<(c+++2) thì ra 5 ah =))
      Be different and always different
      http://archlinuxvn.org/
      http://theslinux.org
      http://lab.infosec.xyz

      Comment


      • #4
        Originally posted by 09520019 View Post
        Mình kết luận là máy 2 bạn có vấn đề
        Mình dùng GNU C++ và Visual Studio 2010 cả 4 trường hợp GNU cin, GNU c=3, VS cin và VS c=3 tất cả đều ra 66

        Nói giỡn thôi chứ chưa thấy toán tử +++ bao giờ, hình như bạn xài HĐH Linux phải ko ? Mình xài Win7, Mình đã thử test server linux và nó ra 4 4 nếu cin
        ++ ưu tiên cao hơn + nên nó ++ rồi mới +
        Xác nhận kết quả 44 trên linux khi dùng cin với g++ (Gentoo 4.5.3-r1 p1.0, pie-0.4.5) 4.5.3

        Comment


        • #5
          vấn đề nằm ở biểu thức c=(c+++2) và cout <<(c+++2)
          ở cout<<(c+++2) có thề giải thích được bằng phép c++ trả về giá trị chưa +1 của c nên kết quả là 5 nhưng đối với c=(c+++2) và c=c+++2 cho ra cùng kết quả là 4 thì không giải thích nổi ah và c=3 khác với cin>>c nhập 3 thế nào ah
          Last edited by 10520058; 01-11-2011, 00:07.
          Be different and always different
          http://archlinuxvn.org/
          http://theslinux.org
          http://lab.infosec.xyz

          Comment


          • #6
            Code:
             int a;std::cin>>a; c= a;
            Như vầy thì nó chạy đúng đây.

            Comment


            • #7
              c = c +++ 2;
              kết quả không được xác định. Đây là những trường hợp nên tránh trong lập trình
              ví dụ khác :
              int i = 7;
              i = ++ i;

              Tham khảo : A-Z of C, Indian Programming world
              nguyendauit@gmail.com

              Comment


              • #8
                thầy cũng bảo tránh khi dạy nhưng muốn biết lí do vì sao lại tránh và lúc chạy nó bị lỗi gì Nguyên ah với lại trường hợp này 2 là const mà nên ++ được giao về phía c
                c = c +++ 2;
                kết quả không được xác định. Đây là những trường hợp nên tránh trong lập trình
                ví dụ khác :
                int i = 7;
                i = ++ i;

                Tham khảo : A-Z of C, Indian Programming world
                Last edited by 10520058; 01-11-2011, 00:23.
                Be different and always different
                http://archlinuxvn.org/
                http://theslinux.org
                http://lab.infosec.xyz

                Comment


                • #9
                  Originally posted by 07520004 View Post
                  Code:
                   int a;std::cin>>a; c= a;
                  Như vầy thì nó chạy đúng đây.
                  vậy sự khác nhau giữa cin>>c và c=const là gì vậy anh
                  Be different and always different
                  http://archlinuxvn.org/
                  http://theslinux.org
                  http://lab.infosec.xyz

                  Comment


                  • #10
                    Originally posted by 10520058 View Post
                    Sau một hồi tranh luận nảy lửa giữa mìn và bạn vẫn chưa có câu trả lời đúng cho trường hợp mình đã gặp phải thế này
                    mình dùng g++ 4.6 (GNU) và bạn mình dùng C-Free C++ 4.6 luôn
                    bài như sau
                    #include<iostream>
                    int main()
                    {
                    int c;
                    std::cin>>c;
                    c=(c+++2);
                    std::cout<<c;
                    std::cout<<c;

                    return 0;
                    }
                    khi chạy trên hai máy khác nhau c=3 kết quả ra khác nhau: mình ra 4 4 bạn mình ra 5 5
                    chư hết nếu thay cin >> c bằng c=3 thì hai kết quả hoàn toàn giống nhau là 6
                    mình muốn hỏi vì sao có sự khác biệt này
                    Cho mình đóng góp chút:
                    Thứ nhất mình không hiểu lắm ý câu này "khi chạy trên hai máy khác nhau c=3"
                    Nếu bạn nói rõ ý chổ này mình xin giải thích vì sao ra 4 4 và 5 5.

                    Ở đây mình chỉ giải thích vì sao với c=3 thì cả 2 đều in ra là 6 6.
                    Với câu lệnh c=(c+++2) thì tạm thời chúng ta có 2 cách hiểu thế này:
                    Thứ nhất: c=((c++)+2) ý nghĩa của (c++) có nghĩa là thực hiện phép tính với c trước, sau đó tăng c lên 1 đơn vị. Vậy ý nghĩa lệnh này là: gán c bằng tổng của c và 2, sau đó tăng c lên 1 đơn vị. Rõ ràng với c= 3 ta có : gán c bẳng tổng của c và 2 ta được 5. Sau đó tăng c lên 1 đơn vị ta được 6.
                    Thứ hai: c=(c+(++2)) ý nghĩa của (++2) là tăng 2 lên một đơn vị trước khi thực hiện phép tính. Vậy ý nghĩa của lệnh này là gán c bằng tổng của c và (++2). Như vậy rõ ràng c= 3+3=6.

                    Nhưng theo thứ tự độ ưu tiên thì Variable++ có độ ưu tiên cao hơn ++Variable. Do đó chọn phương án thứ nhất.

                    Đôi lời chia sẽ, mong các bạn đóng góp thêm. Cái này học bên KTMT gặp hoài..... (
                    **************************************
                    Doan Duy
                    Computer Engineering Department - University of Information Technology
                    Email: duy.doan@icdrec.edu.vn or duyd020990@gmail.com

                    Comment


                    • #11
                      thoe phương án hai của anh thì sẽ gặp lỗi biên dịch ah phương án đầu em đã nghĩ ra rồi ah cám ơn anh ah nhưng sự khác nhau giữa cin>>c và c=3 là chỗ nào vậy anh tại sao c=c+++2 lại ra 4 mà không ra 5 hay 6
                      cm_tam.cpp:7:9: error: lvalue required as increment operand
                      Be different and always different
                      http://archlinuxvn.org/
                      http://theslinux.org
                      http://lab.infosec.xyz

                      Comment


                      • #12
                        Mình có thể đoán sơ sơ nhưng nếu tất cả win đều ra 6, và tất cả linux đều ra 4 thì mình dự đoán như sau:
                        1. trình biên dịch sẽ biên dịch thành c=((c++)+2)
                        2. trên win thì nó sẽ chạy như sau:
                        c = 3
                        c = c + 1 = 4
                        (4)+2 = 6
                        c = (6)

                        trên linux:
                        c = 3
                        c + 1 = 4 // lệnh c = 4 được hoãn lại
                        (4) + 2 = 6
                        c = (6)
                        c = 4 //cái hoãn hồi nãy trả về chỗ này

                        nhưng giả thuyết này xem ra ko hợp lý lắm vì khi gán c = 3 thì chương trình vẫn chạy đúng
                        nhưng mặt khác, mình thử đổi c = (c+++2) thành c = (++c+2) thì kết quả là 6 (win và linux)
                        nhưng bạn nào thử decompile xem nó ra sao - decompile dc đoạn code đó thì xem như ta có kết quả
                        Last edited by 09520019; 01-11-2011, 01:14.
                        Khoảng cách giữa bạn và ước mơ của bạn là bao xa ?

                        Comment


                        • #13
                          Originally posted by 09520019 View Post
                          Mình có thể đoán sơ sơ nhưng nếu tất cả win đều ra 6, và tất cả linux đều ra 4 thì mình dự đoán như sau:
                          1. trình biên dịch sẽ biên dịch thành c=((c++)+2)
                          2. trên win thì nó sẽ chạy như sau:
                          c = 3
                          c = c + 1 = 4
                          (4)+2 = 6
                          c = (6)

                          trên linux:
                          c = 3
                          c + 1 = 4 // lệnh c = 4 được hoãn lại
                          (4) + 2 = 6
                          c = (6)
                          c = 4 //cái hoãn hồi nãy trả về chỗ này
                          em hiểu ý của anh rồi nhưng cái cin>>c và c=3 trong Linux khác nhau như thế nào mà có thể hoãn lại câu lệnh kia lại nhỉ
                          em đoán khác anh ah bước một cũng như anh nhưng bước hai nó tính c++ trước ra 3 cộng hai ra 5 sau đó cộng lại 1 do sau phép c++ cho c ở vế trái tạo ra 6 ( bởi vì phép cout<<c+++2 ra 5)
                          còn trên Linux em không đoán được gì cả bởi nó bị ở cái khúc khác nhau gán c= 3 và cin>>c nhập ba giải quyết được cái náy thì chắc giải quyết xong vấn đề gán c=3 thì vẫn r 6 bt
                          Be different and always different
                          http://archlinuxvn.org/
                          http://theslinux.org
                          http://lab.infosec.xyz

                          Comment


                          • #14
                            Tôi không xem kỹ lắm nhưng có thể do version của trình biên dịch khác nhau nên nhiều khi trình biên dịch sẽ dùng cơ chế left-to-right hay cơ chế right-to-left để parse các câu lệnh. Có thể dùng makefile để chỉnh cái này.
                            :happy:SỐNG TRONG MÁI NHÀ UIT, BẠN HÃY NHỚ :happy:
                            1. Chấp hành pháp luật, tuân thủ nội quy; 2. Tích cực học tập, chủ động nghiên cứu
                            3. Đi học đúng giờ, trang phục lịch sự; 4. Nhớ xếp hàng và đừng chen lấn
                            5. Sống có trách nhiệm và biết sẻ chia; 6. Giữ gìn tài sản chung như tài sản của chính bạn
                            7. Sử dụng tài sản, thời gian hiệu quả; 8. Khiêm tốn, lễ phép, hòa nhã, thân thiện
                            9. Không xả rác để không nhặt rác; 10. Văn minh, lịch sự dù trên lớp học, diễn đàn hay mạng xã hội

                            Comment


                            • #15
                              c+++2
                              Chỉ có thể được phân tích thành (c++)+2 vì toán tử ++ không áp dụng cho hằng số nên c+(++2) là sai cú pháp.

                              Giải thích cách chạy thì:

                              c=c+++2; tương đương với c = c + 2; c = c + 1;

                              như vậy với c = 3 gán sẵn ta có
                              c = 3 + 2 (lúc này c = 5)
                              sau đó
                              c = 5 + 1 (lúc này c = 6)

                              Kết quả ra 6 là đúng với cú pháp

                              Vấn đề là tại sao nó sai khi chạy liên tiếp 2 lệnh cin >> c; c = c+++2 ;
                              Giả thuyết vê việc hoãn lệnh là không hợp lý lắm. Vấn đề là cách handle reference đối với biến vì ta biết toán tử >> đối với class istream nó thay đổi giá trị biến thông qua reference.
                              Để kiểm chứng có phải vấn đề về cách handle reference ta làm một cái thử nghiệm nhỏ với một hàm test thay đổi giá trị thông qua refrence:
                              Code:
                               void test (int &c){ c = 3; }
                              Sau đó ta thay std::cin >> c; bằng test(c); và chạy thử kết quả ra 44


                              Như vậy vấn đề là ở cách hệ thống handle reference đến biến và quản lý bộ nhớ.

                              Tạm thời điều tra tới đây, mai điều tra tiếp, coi nốt cái film the walking dead đang pause dang dở cái đã.

                              Comment

                              LHQC

                              Collapse
                              Working...
                              X