Bài số 19 C++ cơ bản của a Đạt chạy trên Clion

Sao e nhập như thế mà số nguyên là số thực nó ko đổi vậy a?
Nhập ban đầu so_nguyen=101, so_thuc=45,7


[code]#include
#include
#include

using namespace std;
int main(){
int so_nguyen;
double so_thuc;
cout<<“Nhap vao mot so nguyen va mot so thuc \n”;
cin>>so_nguyen>>so_thuc;
cout<<“so_nguyen == “<<so_nguyen <<”\nsonguyen + 1 == “<<so_nguyen+1
<<”\nso_thuc x 3 == “<<so_thuc3
<<"\nso_nguyen^2 == "<<so_nguyen
so_nguyen
<<”\nso_nguyen %2 == “<<so_nguyen%2
<<”\nso_nguyen == “<< so_nguyen << “\n”
<<”\nso_thuc == “<< so_thuc << “\n”;
cout << “\nCac phep tang giam truc tiep”
<<”\nso_nguyen+1==”<<++so_nguyen
<<"\nso_thuc -=3 =="<<(so_thuc -=3)
<<"\nso_nguyen*=2 ==" <<(so_nguyen*=2)
<<"\ncan bac 2 so_thuc ==" << sqrt(so_thuc)
<<"\nsonguyen == “<<so_nguyen
<<”\nsothuc =="<<so_thuc;
return 0;

}[/code]

Em vừa thử với codeblocks kết quả vẫn vậy ?? @ltd
<img src="//daynhauhoc.s3-ap-southeast-1.amazonaws.com/original/2X/8/8ce1fc99b6c4c37543bcf2b8ae6a591386cb4aee.png" width=“690” height=“388” /img>

Bạn debug để xem tuần tự lệnh mà máy chạy có giống bạn hình dung không nhé, có vài điều khá thú vị ở đây

1 Like

cái kiểu viết này cũng là undefined behavior đó bạn

cout << a << a++ << ++a;

vì trong C++ << cũng chỉ là 1 toán tử như + - * /, mà viết ++a + a++ thì là undefined behavior, mỗi compiler dịch ra code khác nhau…

cách sửa là viết tuần tự
cout << a;
cout << a++;
cout << ++a;

@ltd vào sửa bài tập nè :stuck_out_tongue:

2 Likes

Sau khi sửa lại code thì nó ra đúng kết quả rồi, mà e vẫn ko hiểu vì sao :smiley:.

do trình dịch nó dịch theo thứ tự sao cho dịch nhanh đó

    cout << "\nCac phep tang giam truc tiep"
         <<"\nso_nguyen+1=="<<++so_nguyen            //dịch là so_nguyen = so_nguyen + 1 rồi <<so_nguyen
         <<"\nso_thuc -=3 =="<<(so_thuc -=3)         //dịch là so_thuc = so_thuc - 3 rồi <<42.7
         <<"\nso_nguyen*=2 ==" <<(so_nguyen*=2)      //dịch là so_nguyen = so_nguyen*2 rồi <<so_nguyen
         <<"\ncan bac 2 so_thuc ==" << sqrt(so_thuc) //dịch là sqrt(45.7), căn của copy của so_thuc chứ ko phải so_thuc
         <<"\nsonguyen == "<<so_nguyen               //dịch là <<101, tức là output ra copy của so_nguyen chứ ko phải output so_nguyen
        <<"\nsothuc =="<<so_thuc;                    //dịch là <<45.7, tương tự

do (so_nguyen*=2) có dấu () nên nó ưu tiên thực hiện trước, nên so_nguyen = so_nguyen*2 trước khi tất cả operator<< được thực hiện, tương tự ++ cũng được ưu tiên trước <<, nhưng do ko có () nên so_nguyen = so_nguyen + 1 được thực hiện sau. Đáng lẽ operator*= của int phải trả về int&, nhưng có lẽ trình dịch này nó trả về int chứ ko phải trả về reference (tối ưu hóa, với các kiểu nguyên thủy thì trả về bản copy lẹ hơn là trả về reference), nên mới ra 202 thay vì 203 như ++so_thuc trả về int&.

    so_thuc = so_thuc - 3;
    so_nguyen = so_nguyen * 2;
    so_nguyen = so_nguyen + 1;
    cout << "\nCac phep tang giam truc tiep"
         <<"\nso_nguyen+1=="<<so_nguyen
         <<"\nso_thuc -=3 =="<<42.7
         <<"\nso_nguyen*=2 ==" <<202
         <<"\ncan bac 2 so_thuc ==" << sqrt(45.7)
         <<"\nsonguyen == "<<101
        <<"\nsothuc =="<<45.7; //tất cả các tham số đều ko phụ thuộc vào nhau như cách trên nữa

nói chung đây là 1 cách giải thích nhưng chả có nghĩa lý gì. Vì compiler nó phải dịch sao cho các tham số ko phụ thuộc vào nhau như viết ghép ++a + a++, nó thích chuyển sao cũng được, nên mới gọi là undefined behavior - cách xử lý ko xác định, xác định ở đây là chỉ có 1 kết quả duy nhất.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?