01/10/2018, 09:26

Sau 2 lệnh này k bằng mấy? Tại sao

int k =5;
k=k++;

Java hoặc C/C++

vũ xuân quân viết 11:35 ngày 01/10/2018

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.

Hoàng Trung viết 11:41 ngày 01/10/2018

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.

nguyenlehai viết 11:26 ngày 01/10/2018

đầ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

Tung Dao viết 11:36 ngày 01/10/2018

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ử ++

Đức Bảo viết 11:31 ngày 01/10/2018

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)

明玉 viết 11:26 ngày 01/10/2018

Đoạn code mà bạn đưa có thứ tự như sau:
int k = 5;
k = k;
k++;
Vậy k = 6

Trần Hoàn viết 11:34 ngày 01/10/2018

Ô, 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…

Hùng Nguyễn Việt viết 11:38 ngày 01/10/2018

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

Trần Hoàn viết 11:38 ngày 01/10/2018

Không cần cảm ơn nhé

anon51853234 viết 11:28 ngày 01/10/2018

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.

Vesper Link viết 11:41 ngày 01/10/2018

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;
Trần Hoàn viết 11:26 ngày 01/10/2018

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

Vesper Link viết 11:36 ngày 01/10/2018

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

Hồng Quân viết 11:42 ngày 01/10/2018

Bác này nói chuẩn luôn nè!

*grab popcorn* viết 11:35 ngày 01/10/2018

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

Hoàng Trung viết 11:38 ngày 01/10/2018

Câu trả lời hay đây nè, bữa trước có lên stackoverflow cũng có nói như vậy

Nguyên Trần viết 11:29 ngày 01/10/2018

IDE cũng chỉ là 1 công cụ do con người tạo ra, nhiều khi quy ước khác nhau nên khi chạy trên mỗi IDE lại cho 1 kết quả khác nhau. Quan trọng là phải hiểu được lí thuyết của ngôn ngữ và cách hoạt động của IDE, chứ không phải cứ dịch chương trình xong thấy kết quả thì cho rằng luôn luôn đúng.

Nguyễn Quốc Hoàng viết 11:32 ngày 01/10/2018

Undefinded behavior, kết quả không thể tính trước được

Trần Hoàn viết 11:41 ngày 01/10/2018

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 :))

Mimo viết 11:40 ngày 01/10/2018

Mình chắc chắn là = 5 , một vài complier khác sẽ bằng 6

Bài liên quan
0