int k =5;
k=k++;
Java hoặc C/C++
int k =5;
k=k++;
Java hoặc C/C++
theo suy đoán là bằng 6.
int k =5;
k=k++;
toán chạy từ bên phải qua trái. nghĩa là k tăng lên 1 rồi gán lại cho k.
Theo mình biết thì gán trước tăng sau chứ :p. Cái này thuộc về độ ưu tiên của toán tử, bạn thử tìm hiểu về phần đó xem.
đầu tiên k = 5, sau đó gán biến k++ (k tăng thêm 1 đơn vị) => lúc này k = 6
int k =5; => k = 5
k=k++; => lúc đầu k được gán bằng k tức là k = 5, sau đó k được tăng lến tức k = 6
Kết quả cuối cùng là k = 6 nhưng do toán tử ++
k=6
lúc đầu k=5 sau đó biến k +1 lên rồi gán lại cho biến k
tức là k=5 sau đó +1=6 rồi gán lại cho k (cộng trước gán sau)
Đoạn code mà bạn đưa có thứ tự như sau:
int k = 5;
k = k;
k++;
Vậy k = 6
Ô, hoá ra phép gán =
còn được ưu tiên hơn cả phép ++
à O_o
Cứ tưởng k++
return ra 5 thì k = k++;
cũng cho k = 5;
hoá ra mình nhầm…
Em cũng nghĩ bằng 6 nhưng sự thật là bằng 5 nhé các bác không tin thì cứ test thử trên c++ vs java đều thế. Chưa tìm ra lý do tại sao
int k=5;
k=k++;
ban đầu k=5 và giá trị k bên trái dấu gán của k=k++ sẽ =5 , tiếp theo k++ thì k tăng thêm 1 giá trị nên k trở thành 6.
Trong Java
Để làm rõ mình so sánh hai trường hợp, sự khác biệt ở đây là thời điểm giá trị được đẩy vào Stack (Push)
Case 1:
int k = 5; /* 5 được đẩy (push) vào stack và sau đó return về cho k,
hay được lấy ra (Pop) gán cho k */
k = k++; /* Giá trị x hiện tại (5) được push vào stack và sau đó k được
tăng lên 1 là 6, nhưng trong stack vẫn còn giá trị cũ của k
là 5, giá trị này được pop ra và gán cho k, vậy k = 5 */
Case 2:
int k = 5;/* tương tự 5 được đẩy (push) vào stack và sau đó return về cho k,
hay được lấy ra (Pop) gán cho k */
k = ++k; /* k được tăng lên một đơn vị là thành 6, sau đó được
push vào stack, giá trị này sẽ được lấy ra để gán cho k nên k = 6 */
Nếu dấu Increment nằm sau (postfix) thì giá trị của biểu thức bên phải dấu bằng sẽ được đẩy vào stack rồi mới tăng, nên sự tăng ở đây vô nghĩa. Còn nếu ++ nằm trước (prefix) thì nó sẽ tăng rồi mới đẩy vào stack.
Stack ở đây là Operand stack, Operand stack nằm trong Frame, Frame thì nằm trong Stack.
Nếu bạn không hiểu stack là gì thì có thể hiểu quá trình trên như này:
int k = 5;
int tạm = k;
k++;
k = tạm;
Bạn à, mình cũng từng nghĩ như thế, cho đến khi chạy thử
Đã chụp hình Visual C++ ở trên
Cơ chế đấy là trong máy ảo JVM của Java. Còn C++ thì mình ko rõ. Những kết quả mình chạy vẫn là 5.
Hóng chuyên gia C++ vào giải đáp
Bác này nói chuẩn luôn nè!
Cái này được nói rất nhiều lần rồi, search trong forum cũng sẽ không ít topic nói về cái này.
Nó liên quan tới sequence point.
Một rule nhỏ cho C/C++ là ở mỗi sequence point, chỉ được cập nhật 1 biến 1 và 1 lần duy nhất, nếu không thì hành vi của nó sẽ không được xác định (Undefined Behavior)
k = k++ đã vô tình update biến k 2 lần (k++ và phép gán) ở trong cùng 1 sequence point. Và như ở trên, dẫn tới Undefined Behavior
The Standard states that
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
http://c-faq.com/expr/seqpoints.html
Còn Java thì bạn Skyfall nói kỹ luôn rồi
Câu trả lời hay đây nè, bữa trước có lên stackoverflow cũng có nói như vậy
Undefinded behavior, kết quả không thể tính trước được
Mình hiểu điều đó. Nên mình muốn nhắc nhở những người giải thích như đinh đóng cột là k == 5
hoặc k == 6
rồi đưa dẫn chứng dài dằng dặc nửa trang giấy nên suy nghĩ kỹ hơn :))
Mình chắc chắn là = 5 , một vài complier khác sẽ bằng 6