Công cụ bảo vệ mã nguồn .NET mạnh nhất, không thể unpack, miễn phí cho các khách hàng đầu tiên đăng ký.
Từ 1 tới 9 trên tổng số 9 kết quả

Đề tài: Không giải thích được kết quả của phép toán f=++a+(++a);

  1. #1
    Ngày gia nhập
    09 2009
    Bài viết
    16

    Mặc định Không giải thích được kết quả của phép toán f=++a+(++a);

    Mình có phép toán đơn giản nhưng không giải thích được kết quả như sau:

    Code:
    int main()
    {
      int f,a=0;
      f=++a+(++a);  //KQ: f=4, a=2. Tại sao?
    
    }
    Các bạn vui lòng giải thích giúp. Cảm ơn.
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.

    ------------------------------
    Email: pctester2020@gmail.com
    Y!M:pctester2020
    ------------------------------


  2. #2
    Ngày gia nhập
    07 2007
    Nơi ở
    TP HCM
    Bài viết
    66

    Code:
        
       #0   #1   #2   #3
    f  =     ++a  +   (++a);
    bước 1: #3 (++a) được thực thi vì có dấu () nên độ ưu tiên cao hơn, => a = 1
    bước 2: #1 ++a được tính tiếp theo vì ++ có độ ưu tiên hơn, => a = 2
    bước 3: #2 + được tính => 2 + 2 = 4
    bước 4: #0 = phép gán 4 cho f.


    f = 4, a =2

  3. #3
    Ngày gia nhập
    11 2011
    Bài viết
    9

    Các bước xử lý:

    f=++a+(++a) ; f=?, a=0
    (++a) được thực hiện vì nằm trong ngoặc đơn, có độ ưu tiên cao nhất, sẽ được xử lý trước tiên, lúc này a = 1.
    Biểu thức trở thành: f=++a+a

    f=++a+a ; f=?, a=1
    ++a được thực hiện vì toán tử ++ có độ ưu tiên cao hơn toán tử +, lúc này a=2.
    Biểu thức trở thành: f=a+a

    f=a+a ; f=?, a=2
    a+a được thực hiện vì toán tử + có độ ưu tiên hơn toán tử = (phép gán)
    Biểu thức trở thành: f=4

    Gán 4 cho f, cuối cùng f=4 và a=2.

  4. #4
    Ngày gia nhập
    09 2009
    Bài viết
    16

    Cảm ơn 2 bạn trandatnh và zareh.

    Mình thắc mắc ở bước 3: f=(tạm=2)+(tạm=1)=3? Liệu suy luận như vậy có logic?

    ------------------------------
    Email: pctester2020@gmail.com
    Y!M:pctester2020
    ------------------------------


  5. #5
    Ngày gia nhập
    04 2010
    Nơi ở
    Binh Thanh, Hồ Chí Minh, Vietnam, Vietnam
    Bài viết
    504

    Nhân topic này tôi nói chút về trường hợp "undefined behavior". Nếu không có cặp dấu ngoặc thì đây là trường hợp "undefined behavior" - không xác định hành vi. Nếu các bạn đã học qua C++ và biết cách "overload" các toán tử thì toán tử + sẽ có dạng như sau:
    int operator+(const int& _lhs, const int& _rhs);
    Tức là khi viết f=++a + ++a; tương đương với f = operator+(++a, ++a); C/C++ chỉ quy định là tham số của hàm phải được tính trước lời gọi hàm, nhưng không quy định trình tự. Có thể từ trái sang phải, hoặc từ phải sang trái, tùy theo từng compiler khác nhau. Nên kết quả khác nhau không có gì lạ. Nên tránh loại này khi lập trình, không được sử dụng dạng này trong các lời gọi hàm.

    Trích dẫn Nguyên bản được gửi bởi pctester2020 Xem bài viết
    Cảm ơn 2 bạn trandatnh và zareh.
    Mình thắc mắc ở bước 3: f=(tạm=2)+(tạm=1)=3? Liệu suy luận như vậy có logic?
    Đây cũng là trường hợp "undefined behavior", tùy compiler, có cái thì sẽ dùng biến tạm để tính toán các giá trị trong hàm, có cái sẽ không. Trong trường hợp không sử dụng biến tạm, kết quả sẽ ra giống như trong đề bài.
    Đã được chỉnh sửa lần cuối bởi doicanhden : 14-08-2013 lúc 01:08 PM.
    Kết bạn với tôi <3
    Skype: giautm
    Facebook:
    https://fb.com/giautm.duongntt
    Email:
    giau.tmg@gmail.com

  6. #6
    Ngày gia nhập
    04 2013
    Nơi ở
    $HOME
    Bài viết
    48

    Mặc định Không giải thích được kết quả của phép toán f=++a+(++a);

    Độ ưu tiên toán tử không đủ để xác định thứ tự thực tiện của biểu thức. Do đó C/C++ đưa ra thêm khái niệm sequence points. Xem thêm ở đây:

    http://en.wikipedia.org/wiki/Sequence_point
    http://c-faq.com/expr/seqpoints.html

    và nhất là giải thích và các ví dụ ở đây:

    http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points

    Như vậy biểu thức của bạn sẽ cho Undefined behavior.

  7. #7
    Ngày gia nhập
    04 2010
    Nơi ở
    Binh Thanh, Hồ Chí Minh, Vietnam, Vietnam
    Bài viết
    504

    @cvht: Thật sự thì tôi cũng không chắc đây có phải là "Undefined behavior" không nữa. Vì trường hợp này khá đặt biệt, do sự xuất hiện của cặp ngoặc tròn, nó thay đổi sự ưu tiên của toán tử - trong ngoặc được tính trước tiên. Nên lúc này là chỉ phụ thuộc vào một yếu tố là trình biên dịch sử dụng cách nào để lưu trữ các giá trị tham số. Nếu nó dùng tham chiếu f == 4; và a == 2;, nếu là giá trị tạm thì kết quả f == 3; và a == 2;. Nếu tôi nhớ không lầm thì trình biên dịch Turbo-C hay cái đồ cổ gì đó dùng biến tạm? Còn theo chuẩn thì là tham chiếu? Nếu vậy thì đây không phải là "Undefined behavior"
    Kết bạn với tôi <3
    Skype: giautm
    Facebook:
    https://fb.com/giautm.duongntt
    Email:
    giau.tmg@gmail.com

  8. #8
    Ngày gia nhập
    07 2011
    Bài viết
    474

    undefined behavior nghĩa là mỗi compiler có thể sẽ cho ra kết quả khác nhau và chuẩn cũng ko nói là compiler nào đúng, nếu chỉ xài 1 phiên bản của 1 compiler nào đó thì giá trị này luôn xác định được. Nhưng đem code qua compiler khác compile run thì có thể lại ra kết quả khác. Và tiêu chuẩn thì ko bảo rằng compiler nào đúng, compiler nào sai.

    nếu chỉ xài 1 compiler thì đừng lầm tưởng rằng giá trị này xác định. Nó là ko xác định.

  9. #9
    Ngày gia nhập
    04 2010
    Nơi ở
    Binh Thanh, Hồ Chí Minh, Vietnam, Vietnam
    Bài viết
    504

    Chốt: "Undefined behavior". Giá trị biểu thức trên không thể xác định một cách chính xác. Tùy compiler.
    VD: int a = 0; Giá trị của ++a/++a có thể là 1/2, 1 hoặc 2
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.
    Kết bạn với tôi <3
    Skype: giautm
    Facebook:
    https://fb.com/giautm.duongntt
    Email:
    giau.tmg@gmail.com

Các đề tài tương tự

  1. Trả lời: 0
    Bài viết cuối: 27-03-2012, 03:22 PM
  2. Trả lời: 0
    Bài viết cuối: 27-03-2012, 03:09 PM
  3. Trả lời: 0
    Bài viết cuối: 27-03-2012, 03:06 PM
  4. Trả lời: 0
    Bài viết cuối: 27-03-2012, 02:22 PM
  5. Trả lời: 0
    Bài viết cuối: 27-03-2012, 02:01 PM

Tags của đề tài này

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