Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 13 kết quả

Đề tài: Độ ưu tiên của toán tử và trình biên dịch

  1. #1
    Ngày gia nhập
    11 2007
    Nơi ở
    Biết để làm gì?
    Bài viết
    827

    Mặc định Độ ưu tiên của toán tử và trình biên dịch

    1,Mọi người hãy giải thích tại sao đoạn code sau
    Code:
    int c=0;
    cout<<c++<<c++;
    lại cho in ra kết quả 1 0
    2,Tại sao khi cùng biên dịch chương trình sau
    Code:
    #include <iostream.h>
    void main()
    {
    	int c=10,d;
    	d=c++  +  ++c  +  c--  -  --c;
    	cout<<d;
    	cin.get();
    }
    thì VC++6.0 và C-Free cho ra kết quả 23,còn TC++3.0 lại cho ra kết quả 20.Tóm lại thì kết quả nào đúng?
    Cánh Chym ứ mỏi

  2. #2
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Tuỳ vào complier. Cái này thì đúng hay sai thì chắc tuỳ thuộc vào người lập trình, chú ý sao cho nó logic khi code là được. Theo thứ tự thì nó evaluate from left to right. Nhưng đa số sách sau này thì có lẽ cái complier Visual 2008 là chính xác hơn Dev-cpp, cứ hiểu giống như 1 quy luật lập trình vậy, nó phát triển thì mình tiếp thu thôi. Không cần phải quan trọng cái này. Lưu ý ++x và x++ khác nhau chỗ nào là được rồi.

  3. #3
    Ngày gia nhập
    12 2007
    Bài viết
    224

    Những thứ này theo mình chỉ nên biết để mà biết , chứ khi lập trình thực tế đừng nên viết theo lối như vậy , rất dễ sai . Nên viết từ từ , dài 1 chút nhưng chính xác .

  4. #4
    Ngày gia nhập
    11 2006
    Bài viết
    633

    Code:
    #include <iostream>
    using namespace std;
    int main()
    {
        int c = 10,d;
    	d=c++ + ++c + c-- - --c;
    	cout<<d;
    	system("pause");
    	return 0;
    }
    Trước hết là ++c và --c sẽ được tăng, giảm trước khi được tính toán còn c++ và c-- sẽ được tăng giàm sau khi tính toán. Phép tính được thực hiện từ trái qua phải:
    c++ = 10
    ++c = 11 (đúng ra c lúc này là 11 nhưng sau khi thực hiện phép cộng giữa c++ và ++c thì c++ có hiệu lực và c sẽ là 12, d lúc này là 21)
    c-- = 12 (sau phép cộng giữa c++ + ++c và c-- thì c-- có hiệu lực và làm cho c sẽ là 11, d lúc này là 33)
    --c = 10 (sau khi giảm c rồi phép tính - mới được thực hiện nên d có kết quả là 23)
    TurboC lỗi thời rồi, đem nó so sánh với Visual C, Dev C rồi hỏi kết quả nào đúng thì thật là...

  5. #5
    Ngày gia nhập
    10 2007
    Bài viết
    12

    Thông thường thì:
    cout<<c++ ;
    <=>
    cout<<c;
    c = c + 1;
    Còn
    cout<<++c;
    <=>
    c = c+1;
    cout<<c;

    Nhưng có lẽ nó không được quy định thành chuẩn vì vậy điều này tùy thuộc vào trình biên dịch.

    Khi lập trình ,khi không chắc chắn về hành vi của một lệnh hay thứ tự ưu tiên của toán tử... thì nên tránh dùng nó.
    Ví dụ có thể thay thế lệnh:
    cout<<c++;
    bằng
    cout<<c;
    c++;

  6. #6
    Ngày gia nhập
    11 2006
    Bài viết
    633

    Mặc định Độ ưu tiên của toán tử và trình biên dịch

    Xem thêm trong ANSI C++ về độ ưu tiên theo chuẩn mới nhất. Mọi compiler đều phải dựa theo cái này mà làm thôi, turbo C dùn chuẩn ANSIC++ quá cũ, ko phù hợp để sử dụng.

  7. #7
    Ngày gia nhập
    11 2007
    Nơi ở
    Biết để làm gì?
    Bài viết
    827

    Trích dẫn Nguyên bản được gửi bởi huynguyen Xem bài viết
    Xem thêm trong ANSI C++ về độ ưu tiên theo chuẩn mới nhất. Mọi compiler đều phải dựa theo cái này mà làm thôi, turbo C dùn chuẩn ANSIC++ quá cũ, ko phù hợp để sử dụng.
    Híc,biết là nó cũ nhưng mà ở trường tôi vẫn phải dùng đều.Cái vấn đề về trình biên dich đã thông nhưng còn đoạn code
    Code:
    int c=0;
    cout<<c++<<c++;
    thì sao.Mọi người có thể giải thích ko?Tất nhiên là khi làm thì không ai viết code như vậy,nhưng muốn tường tận vấn đề nên mới tham khảo mọi người
    Cánh Chym ứ mỏi

  8. #8
    Ngày gia nhập
    12 2007
    Bài viết
    3

    Trích dẫn Nguyên bản được gửi bởi dieucay555 Xem bài viết
    Híc,biết là nó cũ nhưng mà ở trường tôi vẫn phải dùng đều.Cái vấn đề về trình biên dich đã thông nhưng còn đoạn code
    Code:
    int c = 0;
    cout << c++ << c++;
    thì sao.Mọi người có thể giải thích ko? Tất nhiên là khi làm thì không ai viết code như vậy,nhưng muốn tường tận vấn đề nên mới tham khảo mọi người
    Thì compiler sinh mã thế nào thì chương trình ra kết quả thế ấy thôi . Ta xét đoạn mã asm do compiler MS VC++ 6.0 sinh ra (build ở chế độ debug):
    Code:
    0040F388  |.  C745 FC 00000>MOV [LOCAL.c],0                     ;  <==  c = 0
    0040F38F  |.  8B45 FC       MOV EAX,[LOCAL.c]
    0040F392  |.  8945 F8       MOV [LOCAL.2],EAX
    0040F395  |.  8B4D F8       MOV ECX,[LOCAL.2]                   ;  <==  ecx = 0
    0040F398  |.  51            PUSH ECX                            ; /Arg1
    0040F399  |.  8B55 FC       MOV EDX,[LOCAL.c]                   ; |
    0040F39C  |.  83C2 01       ADD EDX,1                           ; |<==  edx = c + 1
    0040F39F  |.  8955 FC       MOV [LOCAL.c],EDX                   ; |
    0040F3A2  |.  8B45 FC       MOV EAX,[LOCAL.c]                   ; |
    0040F3A5  |.  8945 F4       MOV [LOCAL.3],EAX                   ; |
    0040F3A8  |.  8B4D F4       MOV ECX,[LOCAL.3]                   ; |<==  ecx = 1
    0040F3AB  |.  51            PUSH ECX                            ; |/Arg1
    0040F3AC  |.  8B55 FC       MOV EDX,[LOCAL.c]                   ; ||
    0040F3AF  |.  83C2 01       ADD EDX,1                           ; ||
    0040F3B2  |.  8955 FC       MOV [LOCAL.c],EDX                   ; ||
    0040F3B5  |.  B9 C0894200   MOV ECX,OFFSET example.cout         ; ||
    0040F3BA  |.  E8 D11CFFFF   CALL example.ostream::operator<<    ; |\ostream::operator<<
    0040F3BF  |.  8BC8          MOV ECX,EAX                         ; |
    0040F3C1  |.  E8 CA1CFFFF   CALL example.ostream::operator<<    ; \ostream::operator<<
    Nếu bạn không rành asm thì có thể tóm lại vậy cho dễ hiểu (cái này hông phải ngôn ngữ gì đâu nha ^^):
    Code:
    c = 0             
    push c          ; push 0
    c = c + 1
    push c          ; push 1
    c = c + 1
    call cout<<
    call cout<<
    Trong asm thông thường việc truyền tham số cho một hàm thực hiện bằng cách push giá trị vào stack, mà stack làm việc theo chế độ LIFO (last in first out).
    Ở đây '1' được push vào sau nên trờ thành tham số cho hàm cout << đầu tiên, '0' push vào trước nên là tham số của hàm cout << thứ hai. Vì vậy ra kết quả là '10' .
    Còn tại sao compiler sinh mã gì mà "kỳ cục" vậy thì bạn hỏi mấy cha code ra cái compiler á
    Hic, hem biết giải thích vậy có gọi là giải thích hông nữa T__T

  9. #9
    Ngày gia nhập
    11 2007
    Nơi ở
    Biết để làm gì?
    Bài viết
    827

    Trích dẫn Nguyên bản được gửi bởi error Xem bài viết
    Thì compiler sinh mã thế nào thì chương trình ra kết quả thế ấy thôi . Ta xét đoạn mã asm do compiler MS VC++ 6.0 sinh ra (build ở chế độ debug):
    Code:
    0040F388  |.  C745 FC 00000>MOV [LOCAL.c],0                     ;  <==  c = 0
    0040F38F  |.  8B45 FC       MOV EAX,[LOCAL.c]
    0040F392  |.  8945 F8       MOV [LOCAL.2],EAX
    0040F395  |.  8B4D F8       MOV ECX,[LOCAL.2]                   ;  <==  ecx = 0
    0040F398  |.  51            PUSH ECX                            ; /Arg1
    0040F399  |.  8B55 FC       MOV EDX,[LOCAL.c]                   ; |
    0040F39C  |.  83C2 01       ADD EDX,1                           ; |<==  edx = c + 1
    0040F39F  |.  8955 FC       MOV [LOCAL.c],EDX                   ; |
    0040F3A2  |.  8B45 FC       MOV EAX,[LOCAL.c]                   ; |
    0040F3A5  |.  8945 F4       MOV [LOCAL.3],EAX                   ; |
    0040F3A8  |.  8B4D F4       MOV ECX,[LOCAL.3]                   ; |<==  ecx = 1
    0040F3AB  |.  51            PUSH ECX                            ; |/Arg1
    0040F3AC  |.  8B55 FC       MOV EDX,[LOCAL.c]                   ; ||
    0040F3AF  |.  83C2 01       ADD EDX,1                           ; ||
    0040F3B2  |.  8955 FC       MOV [LOCAL.c],EDX                   ; ||
    0040F3B5  |.  B9 C0894200   MOV ECX,OFFSET example.cout         ; ||
    0040F3BA  |.  E8 D11CFFFF   CALL example.ostream::operator<<    ; |\ostream::operator<<
    0040F3BF  |.  8BC8          MOV ECX,EAX                         ; |
    0040F3C1  |.  E8 CA1CFFFF   CALL example.ostream::operator<<    ; \ostream::operator<<
    Nếu bạn không rành asm thì có thể tóm lại vậy cho dễ hiểu (cái này hông phải ngôn ngữ gì đâu nha ^^):
    Code:
    c = 0             
    push c          ; push 0
    c = c + 1
    push c          ; push 1
    c = c + 1
    call cout<<
    call cout<<
    Trong asm thông thường việc truyền tham số cho một hàm thực hiện bằng cách push giá trị vào stack, mà stack làm việc theo chế độ LIFO (last in first out).
    Ở đây '1' được push vào sau nên trờ thành tham số cho hàm cout << đầu tiên, '0' push vào trước nên là tham số của hàm cout << thứ hai. Vì vậy ra kết quả là '10' .
    Còn tại sao compiler sinh mã gì mà "kỳ cục" vậy thì bạn hỏi mấy cha code ra cái compiler á
    Hic, hem biết giải thích vậy có gọi là giải thích hông nữa T__T
    Hehe,hiểu rùi .thanks error nhé
    Cánh Chym ứ mỏi

  10. #10
    Ngày gia nhập
    03 2009
    Bài viết
    1

    [QUOTE=dieucay555;32851]1,Mọi người hãy giải thích tại sao đoạn code sau
    Code:
    int c=0;
    cout<<c++<<c++;
    lại cho in ra kết quả 1 0


    Mình nói ngắn gọn cho bạn dễ hiểu thế này :
    Lúc đầu c = 0 , lệnh cout đầu tiên đc thực hiện nên in ra 0 , sau đó c tăng 1
    Lúc này c = 1 , lệnh cout tiếp theo đc thực hiện nên in ra 1 ,sau đó c tăng 1
    Lúc này c = 2 nhưng mà ko có cout nữa nên thoát chương trình

Các đề tài tương tự

  1. Biên dịch bằng C-free gặp lỗi không thể biên dịch được?
    Gửi bởi themanhbk trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 28
    Bài viết cuối: 06-10-2015, 05:45 PM
  2. Lập trình C In k số nguyên tố đầu tiên có tổng các chữ số là chắn trong mảng, lỗi chỉ kiểm tra được với số đầu tiên?
    Gửi bởi ncn1992vn trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 5
    Bài viết cuối: 23-11-2012, 10:20 PM
  3. Kỹ thuật C++ từ trình biên dịch Borland C++ sang trình biên dịch Dev-C++ bị lỗi
    Gửi bởi 0baohbotay1 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 11-08-2012, 11:14 PM
  4. [bada] thư viện static lib do gcc biên dịch ra trong app được biên dịch g++
    Gửi bởi Iphone4 trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 2
    Bài viết cuối: 10-08-2011, 04:53 PM
  5. Lấy chuỗi đầu tiên giữa 2 "biên" trong RegEx với lập trình C#
    Gửi bởi sting2582000 trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 2
    Bài viết cuối: 03-03-2011, 11:45 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn