Tôi sẽ bắt đầu từ câu hỏi cuối cùng của bạn
Ngoài ra, tại sao trình biên dịch hoặc IDE không phàn nàn về hàm main () không trả về int?
Theo tiêu chuẩn C ++ (chức năng chính 6.6.1)
5 Một câu lệnh return trong main có tác dụng rời khỏi hàm main (hủy mọi đối tượng có thời lượng lưu trữ tự động) và gọi std :: exit với giá trị trả về làm đối số. Nếu điều khiển chảy ra khỏi phần cuối của câu lệnh ghép, thì hiệu ứng tương đương với trả về với toán hạng 0 (xem thêm 18.3).
Và liên quan đến câu hỏi này
Làm thế nào là điều này có thể, vì y = 5 không phải là biểu thức có thể tính toán được?
Từ Tiêu chuẩn C ++ (Toán tử gán và chuyển nhượng hỗn hợp 8.18)
1 Toán tử gán (=) và toán tử gán gán tổng hợp tất cả các nhóm từ phải sang trái. Tất cả đều yêu cầu một giá trị có thể sửa đổi là toán hạng bên trái của chúng và trả về một giá trị tham chiếu đến toán hạng bên trái.
Sp tuyên bố này
int x{ y = 5 };
có thể được chia thành hai câu
y = 5;
int x{ y };
Ngoài ra, trong C ++, bạn thậm chí có thể tạo tham chiếu đến biến y theo cách sau
int &x{ y = 5 };
Đây là một chương trình trình diễn
#include <iostream>
int main()
{
int y;
int &x{ y = 5 };
std::cout << "y = " << y << '\n';
x = 10;
std::cout << "y = " << y << '\n';
}
Đầu ra của nó là
y = 5
y = 10
Bạn có thể tuyên bố này
int x{ y = 5 };
viết lại cũng thích
int x = { y = 5 };
Tuy nhiên, hãy tính đến việc có một sự khác biệt giữa những điều này (trông tương tự như các tuyên bố trên) hai khai báo.
auto x{ y = 5 };
và
auto x = { y = 5 };
Trong khai báo đầu tiên biến x
có loại int
. Trong khai báo thứ hai, biến x
có loại std::initializer_list<int>
.
Để làm cho sự khác biệt rõ hơn, hãy xem cách các giá trị của các đối tượng được xuất ra.
#include <iostream>
int main()
{
int y;
auto x1 { y = 5 };
std::cout << "x1 = " << x1 << '\n';
auto x2 = { y = 10 };
std::cout << "*x2.begin()= " << *x2.begin() << '\n';
std::cout << "y = " << y << '\n';
return 0;
}
Đầu ra của chương trình là
x1 = 5
*x2.begin()= 10
y = 10
y = 5
là một biểu thức, và nó có giá trị5
. Tại sao bạn nghĩ rằng nó không phải là?