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
Announcement
Collapse
No announcement yet.
Xin giúp đỡ về toán tử x++
Collapse
X
-
Be different and always different
http://archlinuxvn.org/
http://theslinux.org
http://lab.infosec.xyz
-
Originally posted by 10520058 View PostSau 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
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áLast edited by 10520074; 20-11-2011, 12:47.
Comment
-
Originally posted by 10520074 View PostTạ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
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
Precedence of operators
1 :: scope Left-to-right
2 () [] . -> ++ -- dynamic_cast static_cast reinterpret_cast const_cast typeid postfix Left-to-right
3 ++ -- ~ ! sizeof new delete unary (prefix) Right-to-left
* & indirection and reference (pointers)
+ - unary sign operator
4 (type) type casting Right-to-left
5 .* ->* pointer-to-member Left-to-right
6 * / % multiplicative Left-to-right
7 + - additive Left-to-right
8 << >> shift Left-to-right
9 < > <= >= relational Left-to-right
10 == != equality Left-to-right
11 & bitwise AND Left-to-right
12 ^ bitwise XOR Left-to-right
13 | bitwise OR Left-to-right
14 && logical AND Left-to-right
15 || logical OR Left-to-right
16 ?: conditional Right-to-left
17 = *= /= %= += -= >>= <<= &= ^= |= assignment Right-to-left
18 , comma Left-to-rightLast edited by 09520019; 20-11-2011, 12:51.Khoảng cách giữa bạn và ước mơ của bạn là bao xa ?
Comment
-
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
Comment