Tại sao int x {y = 5} có thể?


10
int main() {
    int y;
    int x{ y = 5 };
    //x is 5
}

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?

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?


8
y = 5 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à?
Vô dụng

2
Liên quan đến thiếu returncủa main, xem câu hỏi này .
quả óc chó

3
Tốt hơn nữa, loại bỏ câu hỏi thứ hai. Một câu hỏi duy nhất cho mỗi câu hỏi là mô hình ưa thích trên Stack Overflow.
Người kể chuyện - Unslander Monica

Có lẽ bạn nên xác định lại câu hỏi tại sao y = 5mang lại 5 ở đây. Khả năng các toán tử gán để trả về một cái gì đó thực sự là một tính năng kỳ lạ của C / C ++.
dùng7860670

Câu trả lời:


11

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 };

auto x = { y = 5 };

Trong khai báo đầu tiên biến xcó loại int. Trong khai báo thứ hai, biến xcó 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

16

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?

Đó là một phép gán và các giá trị mang lại các giá trị, tức là "loại không đủ tiêu chuẩn của toán hạng bên trái", xem [expr.ass / 3] . Do đó, y = 5kết quả y5, được sử dụng để khởi tạo x.

Đối với câu hỏi thứ hai của bạn, hãy xem cppreference trên main (hoặc [basic.start.main / 5] ):

Phần thân của hàm main không cần chứa returncâu lệnh: nếu điều khiển đạt đến cuối của main mà không gặp phải một returncâu lệnh, thì hiệu quả là việc thực thi return 0;.

Do đó, trình biên dịch hoặc IDE cảnh báo bạn về một returncâu lệnh bị thiếu ở cuối mainsẽ hoàn toàn sai. Phải thừa nhận rằng, thực tế là bạn nên luôn luôn returnphản đối từ các voidhàm không được thực thimain là loại ... tốt, vì lý do lịch sử tôi đoán.


2
Một biểu thức có thể dẫn đến một giá trị, nhưng chỉ một hàm có thể return. -pedantic
Vô dụng

Tôi nghĩ rằng int x {y = 5}; tuyên bố không hợp lệ trong c
bhura

@bhura - câu hỏi là về C ++, không phải C
Người kể chuyện - Unslander Monica

Có lẽ đáng để đề cập rằng, ngay cả khi không bắt buộc, vẫn trả lại một giá trị từ chính thường được coi là thực hành tốt?
Aconcagua

4

Các operator=()kết quả trong một giá trị, là giá trị được gán cho biến. Vì điều này, có thể xâu chuỗi các bài tập như thế này:

int x, y, z;
x = y = z = 1;

Các biểu hiện nhiệm vụgiá trị . Hàm có giá trị trả về; biểu hiện không.
Pete Becker

3

Nếu bạn xem tài liệu về cppreference , bạn sẽ thấy rằng operator=()trả về một tham chiếu đến đối tượng đã được chỉ định. Do đó, một phép gán có thể được sử dụng như một biểu thức trả về đối tượng đã được gán.

Sau đó, nó chỉ là một nhiệm vụ bình thường với niềng răng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.