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

Đề tài: [C++] Thứ tự đánh giá các đối số khi gọi hàm trong C/C++

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

    Mặc định [C++] Thứ tự đánh giá các đối số khi gọi hàm trong C/C++

    Thứ tự đánh giá các đối số khi gọi hàm trong C/C++.

    Giả sử chúng ta gọi hàm như sau :

    f( bt1 * g( bt2 ), bt3 * h( bt4 ) );

    với g, h là những hàm và bt1, bt2, bt3, bt4 là 4 biểu thức.

    Câu hỏi đặt ra, đối với chuẩn của C/C++ thì thứ tự tính giá trị (evaluate) của 4 biểu thức bt1, bt2, bt3, bt4 xảy ra như thế nào ? bt1 tính truớc hay bt2 tính trước ....

    Có thể một số bạn nghĩ rằng thứ tự đánh giá sẽ là bt1, bt2, g( ...),
    bt3, bt4, h(...) theo như sự xuất hiện của các biểu thức khi gọi hàm f. Hoặc một số bạn khác nghĩ, thứ tự đánh giá phải là bt3, bt4, h(...), bt1, bt2, g( ...) vì cho rằng các đối số bên phải sẽ được cho vào stack trước.

    Rất tiếc, cả hai câu trả lời trên không đúng cho trường hợp tổng quát. Ngôn ngữ C/C++ cho phép các compiler được tự do lựa chọn về thứ tự đánh giá các đối số, miễn là tuân theo những yêu cầu cơ bản sau (xem thêm ghi chú 2):

    • 1. Các đối số phải được đánh giá trước khi gọi hàm

    • 2. Một khi hàm được gọi rồi thì nó sẽ thực hiện từ đầu đến cuối (sẽ giải thích thêm)

    • 3. Các đối số có thể đánh giá theo thứ tự bất kỳ, có thể chỉ đánh giá một phần trong đối số này, sau đó nhảy sang đối số khác để đánh giá rồi quay ngược lại. Qui tắc này được cho phép nếu nó không va chạm với những qui tắc khác.


    Từ qui tắc 1, chúng ta rút ra điều gì :
    • bt2 phải được đánh giá trước khi g(...) được gọi

    • bt4 phải được đánh giá trước khi h(...) được gọi

    • bt1 * g( bt2 ) và bt3 * h( bt4 ) phải được đánh giá trước khi f(...) đuợc gọi


    Từ qui tằc 3, có thể thứ tự đánh giá xảy ra có thể xảy ra như sau :
    • một phần bt2 có thể được đánh giá trước

    • sau đó nhảy sang đánh giá bt1

    • tính bt4 và h(...)

    • quay lại tính phần còn lại của bt2

    • ...


    Giải thích thêm về qui tắc 2, giả sử hàm g(...) đã được gọi thì hàm g phải được thực hiện từ đầu đến cuối, không có chuyện đang thực hiện hàm g giữa chừng, ngừng lại quay qua đánh giá các biểu thức khác hoặc quay qua gọi hàm h(...) (đừng để ý đa luồng [multi-thread] ở đây)

    Vì thứ tự đánh giá các đối số là phụ thuộc vào người viết compiler, dẫn tới việc nếu bạn gọi hàm với các đối số khá phức tạp thì có xảy ra chuyện, code của bạn có thể đúng với compiler này nhưng sai với compiler khác.

    Cuối cùng, chắc có bạn thắc mắc tại sao ngôn ngữ C/C++ lại cho phép compiler tự do như vậy ? Lý do, là để compiler dễ dàng "tối ưu hoá" .

    Các bạn xem thêm thread này nhé http://www.vninformatics.com/cgi-bin...&msg=996985069

    Nguồn diendantinhoc.net.
    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!

  2. #2
    Ngày gia nhập
    12 2006
    Bài viết
    9

    Mặc định Hỏi một chút

    Chào các bạn. mình mới bắt đầu học C++. mình không phải là dân chuyên nghiệp về CNTT. mình mới học C++ một thời gian mình không hiểu sao khi mình muốn sạo thảo một chương trình C++ đồ họa. khi mình dịch thì không có lỗi gì. những không chạy được. mình còn nguyên phần đồ họa chưa học được gì cả. mong các bạn giúp đỡ.
    cảm ơn các ban.
    chúc các bạn thành công.

  3. #3
    Ngày gia nhập
    12 2006
    Bài viết
    72

    Lỗi này mình thấy hay gặp trong các chương trình có khởi động hệ đồ họa của C++, bạn xem bài dưới đây có phải lỗi của bạn không? Nếu phải thì ở đó có luôn cách khắc phục rồi đó:
    http://forums.congdongcviet.com/showthread.php?t=755

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