2015-09-30 24 views
5

Giá trị trả về của f (p, p), nếu giá trị p là được khởi tạo thành 5 trước cuộc gọi? Lưu ý rằng tham số đầu tiên là được truyền theo tham chiếu, trong khi thông số thứ hai được chuyển theo giá trị.Hành vi không xác định trong mã đã cho?

int f (int &x, int c) { 
     c = c - 1; 
     if (c==0) return 1; 
     x = x + 1; 
     return f(x,c) * x; 
} 

Tùy chọn là:


Tôi cố gắng giải thích:


Trong mã này, sẽ có bốn cuộc gọi đệ quy với tham số (6,4), (7,3), (8,2) và (9,1). Cuộc gọi cuối cùng trả về 1. Nhưng do vượt qua tham chiếu, x trong tất cả các hàm trước bây giờ là 9. Do đó, giá trị được trả về bởi f (p, p) sẽ là 9 * 9 * 9 * 9 * 1 = 6561.


Câu hỏi này là từ kỳ thi cạnh tranh GATE, (see Q.no.-42). Phím trả lời được đưa ra bởi GATE "Nhãn hiệu cho tất cả" (có nghĩa là không có tùy chọn chính xác.) key set-C, Q.no.-42. Một nơi nào đó được giải thích là:

Trong GATE 2013, nhãn hiệu được gán cho tất cả giống như mã trong C/C++ tạo ra hành vi không xác định. Điều này là do * không phải là một điểm chuỗi trong C/C++. Mã đúng phải thay thế

return f(x,c) * x; 

với

res = f(x,c); 
return res * x; 

Nhưng mã cho hoạt động tốt. Khóa của GATE có sai không? Hoặc thực sự là sai lầm với câu hỏi?

+2

Một trong những điều có thể xảy ra nếu bạn băng qua đường mà không cần tìm cả hai cách là bạn chuyển sang phía bên kia một cách an toàn. Nhưng đó là một lỗi để * dự đoán * rằng một người đi qua đường mà không cần tìm cả hai cách sẽ làm cho nó sang phía bên kia một cách an toàn. –

+0

Tương tự như [Miêu tả điểm mơ hồ, hành vi không xác định?] (Http://stackoverflow.com/q/29513572/1708801) –

Trả lời

14
return f(x,c) * x; 

Kết quả của thao tác này tùy thuộc vào thứ tự hai thứ được đánh giá. Vì bạn không thể dự đoán thứ tự chúng sẽ được đánh giá, bạn không thể dự đoán kết quả của hoạt động này.

+0

thưa bạn, tại sao hoạt động tốt ở đây [this-code] (http://cpp.sh/8m6y) –

+5

@ user4791206 Ý của bạn là gì bởi "hoạt động tốt"? Vì bạn không thể dự đoán nó sẽ làm gì, tại sao bạn lại nói điều gì xảy ra là nó hoạt động tốt? Một người nào đó dự đoán nó sẽ đánh giá theo thứ tự khác sẽ không nói nó hoạt động tốt, phải không? –

+0

Có nghĩa là, vấn đề về thứ tự đánh giá là hành vi không xác định [I-read] (http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points)? –

9

C++ 03 chương 5:

Trừ khi có ghi chú, trình tự đánh giá của các toán hạng của các nhà khai thác cá nhân và subexpressions của cá nhân biểu thức, và thứ tự mà tác dụng phụ xảy ra, là không xác định.

Vì vậy, trong trường hợp f(x,c) * x, thứ tự đánh giá toán hạng không xác định, có nghĩa là bạn không thể biết toán hạng trái hay phải sẽ được đánh giá trước.

Mã của bạn có hành vi không xác định, có nghĩa là nó sẽ hoạt động theo cách được xác định nhất định chỉ được biết đến trình biên dịch.Lập trình viên không thể biết mã sẽ làm gì, chỉ rằng nó sẽ đánh giá toán hạng bên trái trước tiên hoặc toán hạng bên phải trước tiên. Trình biên dịch thậm chí còn được phép thay đổi thứ tự đánh giá trên cơ sở từng trường hợp, cho mục đích tối ưu hóa.

Nếu thứ tự đánh giá có vấn đề, bạn cần phải viết lại mã. Mã dựa trên hành vi không xác định luôn luôn là một lỗi, có thể là một lỗi khá tinh vi mà sẽ không ngay lập tức bề mặt.

Hành vi không xác định khác với hành vi không xác định, điều này có nghĩa là mọi thứ đều có thể xảy ra, bao gồm chương trình đang chạy hoặc gặp trục trặc hoặc bị lỗi.

+2

Như một lưu ý phụ, cùng một văn bản là khác nhau trong C++ 11 nhưng có ý nghĩa rất giống nhau. Tôi nghĩ C++ 11 (và C11) chỉ làm cho văn bản khó hiểu hơn nhiều, tại sao tôi trích dẫn một phiên bản cũ của tiêu chuẩn. – Lundin

+0

Cảm ơn bạn, tôi hiểu rồi. –

+0

Nói chung "hành vi không xác định" không có nghĩa là một lập trình viên không thể biết mã sẽ làm gì - chỉ đơn thuần là lập trình viên không thể biết trong bất kỳ trường hợp nào mà các trình biên dịch có thể chọn. Nếu tất cả các kết hợp có thể có của hành vi trình biên dịch sẽ đáp ứng các yêu cầu của lập trình viên, thì một lập trình viên sẽ có quyền mong đợi chương trình hoạt động chính xác. Không có gì sai với mã dựa trên một trình biên dịch lựa chọn trong thời trang không xác định từ trong số các hành động được xác định, miễn là nó sẽ làm việc với bất kỳ lựa chọn nào như vậy trình biên dịch sẽ xảy ra. – supercat

Các vấn đề liên quan