If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.
chiều nay em nghe anh Khương nói do cách IDE parse trước khi xuống compiler nhưng em nghĩ là không phải nếu đúng như vậy thì c=3 cũng sẽ bị lỗi do lỗi ở đoạn c=c+++2 em nghĩ vậy ah
Sau một hồi tranh luận nảy lửa giữa mìn và bạn vẫn chưa có câu trả lời đúng cho trường hợp mình đã gặp phải thế này
mình dùng g++ 4.6 (GNU) và bạn mình dùng C-Free C++ 4.6 luôn
bài như sau
#include<iostream>
int main()
{
int c;
std::cin>>c;
c=(c+++2);
std::cout<<c;
std::cout<<c;
return 0;
}
khi chạy trên hai máy khác nhau c=3 kết quả ra khác nhau: mình ra 4 4 bạn mình ra 5 5
chư hết nếu thay cin >> c bằng c=3 thì hai kết quả hoàn toàn giống nhau là 6
mình muốn hỏi vì sao có sự khác biệt này
Tại sao c = aConst và c nhập từ bàn phím lại cho 2 kết quả khác nhau. Sau một hổi test thì mình thấy thế này (GNU GCC) Thứ nhất với c = aConst (c=3 trong bài này): kết quả là 6, có thể giải thích như sau:
c = 3; // gán c = 3 (một hằng số)
c=(c++ +2); //bắt đầu xâu xé phép toán này
c++: dùng c trước: (c++ +2) sẽ trả về 5 (3+2), sau đó gán cho c (c = 5), rồi c mới được tăng lên 1 => c=6 Toán tử gán thực hiện sau ++ và + Thứ 2 với c được nhập từ bàn phím:
Lúc này độ ưu tiên của các phép toán lại không như trường hợp c = aConst (thật khó hiểu): kết quả là 4
cin>>c; //nhập c từ bàn phím (3)
c=c++ +2;
Theo như toán từ ++ thì c được sử dụng trước, và lúc này toán tử gán lại được thực hiện trước tiên (c = 3 sẽ được gán lại cho c). Sau đó c được tăng lên 1
=> lúc này c = 4
+ 2 sẽ thực hiện sau nên không có ý nghĩa với c (toán tử gán đã thực hiện trước rồi). Các bạn có thể kiểm chứng điều này bằng cách thay số 2 bằng số 10000 hay số nào đó thì kết quả không thay đổi. Rõ ràng có thể thấy cùng 1 biến, 2 cách đặt giá trị khác nhau lại khiến độ ưu tiên của phép toán bị thay đổi. Điều này ai nghiên cứu ra tại sao thì post lên cho anh em mở mang
ps: anh An nghiên cứu ra chưa vậy, hồi hộp quá
Tại sao c = aConst và c nhập từ bàn phím lại cho 2 kết quả khác nhau. Sau một hổi test thì mình thấy thế này (GNU GCC)
Thứ nhất với c = aConst (c=3 trong bài này): kết quả là 6, có thể giải thích như sau:
c = 3; // gán c = 3 (một hằng số)
c=(c++ +2); //bắt đầu xâu xé phép toán này
c++: dùng c trước: (c++ +2) sẽ trả về 5 (3+2), sau đó gán cho c (c = 5), rồi c mới được tăng lên 1 => c=6 TOÁN TỬ GÁN THỰC HIỆN SAU CÁC TOÁN TỬ ++ và +
Thứ 2 với c được nhập từ bàn phím:
Lúc này độ ưu tiên của các phép toán lại không như trường hợp c = aConst (thật khó hiểu): kết quả là 4
cin>>c; //nhập c từ bàn phím (3)
c=c++ +2;
Theo như toán từ ++ thì c được sử dụng trước, và lúc này toán tử gán lại được thực hiện trước tiên (c = 3 sẽ được gán lại cho c). Sau đó c được tăng lên 1
=> lúc này c = 4
+ 2 sẽ thực hiện sau nên không có ý nghĩa với c (c đã được gán bằng 3 rồi). Các bạn có thể kiểm chứng điều này bằng cách thay số 2 bằng số 10000 hay số nào đó thì kết quả không thay đổi. Rõ ràng có thể thấy cùng 1 biên, 2 cách đặt giá trị khác nhau lại khiến độ ưu tiên của phép toán bị thay đổi. Điều này ai nghiên cứu ra tại sao thì post lên cho anh em mở mang
Vậy tại sao trên win và trên linux lại ra khác nhau với cùng 1 code ?
Thứ 2 là tại sao toán tử gán lại được thực hiện trước ? Cái này là vô lý vì c = c++ +2 <=> c = (c = c + 1) + 2 (tức là có 2 lần gán xảy ra), thì phép toán ++ đâu có gì ảnh hưởng tới phép gán = ? Theo như GNU thì từ trái sang phải, phép toán gán là phép toán có thứ tự ưu tiên sau cùng, và là phép toán làm từ phải qua trái
Ở đây cho thấy Operator = có thứ tự ưu tiên ở hàng số 17, trong khi phép cộng có thứ tự ưu tiên ở hàng 7, phép ++ ở hàng 3 => theo thứ tự phải làm phép ++, +, = , dù bạn có thảy cho nó bao nhiêu dấu khoảng trắng
Trong cùng một câu lệnh (statement) lại có tới 2 thao tác thay đổi giá trị của biến (phép toán = và ++) sẽ dấn đến một undefined behavior. Specification của C không đề cập đến các trường hợp này và cho phép trình biên dịch tự do cài đặt mục đích là để đơn giản hóa việc xây dựng trình biên dịch cũng như cho phép trình biên dịch có thể cài đặt thêm các phần tối ưu hóa mã máy được sinh ra.
Nói chung bó cái váy túm cái gọn lại là: KHÔNG BAO GIỜ ĐƯỢC CODE CÁI KIỂU x = x++ +wtf như thế này
Comment