2011-01-27 46 views
10

Khi tôi chạy chương trình này:C++ trở lại giá trị mà không trả lại tuyên bố

#include <iostream> 

int sqr(int&); 

int main() 
{ 
    int a=5; 
    std::cout<<"Square of (5) is: "<< sqr(a) <<std::endl; 
    std::cout<<"After pass, (a) is: "<< a <<std::endl; 
    return 0; 
} 

int sqr(int &x) 
{ 
    x= x*x; 
} 

tôi có kết quả như sau:

Square of (5) is: 2280716 
After pass, (a) is: 25 

2280716 là gì? Và, làm thế nào tôi có thể nhận được một giá trị trả lại cho sqr(a) trong khi không có câu hỏi return trong hàm int sqr(int &x)?

Cảm ơn.

+6

WTF? Tại sao bạn muốn viết mã như vậy? Rõ ràng sqr là một hàm toán học và nó không có ý nghĩa để sử dụng tham số như trong-ra. –

+0

@Ilya Kogan. Chỉ cần kiểm tra cách vượt qua bằng cách tham chiếu hoạt động – Simplicity

Trả lời

28

Nghiêm túc, điều này gây ra hành vi không xác định. Trong thực tế, kể từ sqr đã trả về loại int, nó sẽ luôn trả về một cái gì đó, ngay cả khi không có câu hỏi return nào có mặt. Giá trị đó có thể là bất kỳ giá trị int nào.

Thêm tuyên bố return và bật cảnh báo trong trình biên dịch của bạn (ví dụ: g++ -Wall).

int sqr(int &x) 
{ 
    return x = x*x; 
} 
+5

+1 cho '-Wall'. (Bây giờ, nếu bạn thêm '-Werror' ... không, tôi không thể upvote hai lần, damn. :-)) –

+2

Nó là một chút ít đơn giản, không trả lại bất cứ điều gì trong một chức năng với một loại trả lại khác hơn 'void' gây ra hành vi không xác định, không chỉ trả về giá trị không xác định. Sự khác biệt là nói rằng nó sẽ trả về một giá trị không xác định có nghĩa là bằng cách đơn giản bỏ qua giá trị đó mọi thứ sẽ ổn, nhưng điều đó không phải vậy. Chương trình có thể gặp sự cố, làm hỏng ngăn xếp ... –

+2

@David chỉ để làm rõ bit hành vi không xác định và đảm bảo rằng tôi hiểu hoàn toàn vấn đề; nếu, ví dụ, giá trị trả về của chúng tôi là unique_ptr , không có câu lệnh trả về, hàm sẽ trả về rác thay cho T *, sau đó sẽ được người gọi hiểu là unique_ptr hợp lệ và thậm chí nếu bạn bỏ qua nó, giả mạo destructor unique_ptr sẽ sụp đổ chương trình của bạn (hy vọng) trong khi cố gắng xóa pointee của nó. – enobayram

7

Đó là một số rác sẽ phụ thuộc vào một số yếu tố. Có khả năng đó là giá trị được lưu trữ trong bộ nhớ, nơi hàm sẽ đặt kết quả nếu nó có câu lệnh return. Đó là bộ nhớ còn lại untoched và sau đó đọc bởi người gọi.

Đừng nghĩ quá nhiều - chỉ cần thêm câu hỏi return.

3

Bạn đang cố gắng in giá trị trả về của sqr (int & x), là giá trị rác trong trường hợp này. Nhưng không trả lại X * X đúng. thử trở về giá trị X * X từ SQE

int sqr(int &x) { x= x*x; return x;}

4

Chức năng của bạn sqr() không có câu lệnh return. Hàm có hành vi không xác định liên quan đến giá trị trả lại. Đầu ra đầu tiên của bạn cho thấy giá trị trả lại này.

Trình biên dịch sẽ hiển thị chẩn đoán.

thử điều này:

int sqr(int x) 
{ 
    return x*x; 
} 
+0

'g ++' không hiển thị cảnh báo trừ khi '-W' được đưa ra. –

+0

@larsmans. Cú pháp sử dụng '-W' là gì? 'g ++ .....' Cảm ơn – Simplicity

+0

'g ++ -Wall' để cảnh báo mặc định. Kiểm tra hướng dẫn cho các cảnh báo cụ thể. –

1

Nếu một chức năng không được khai báo void sau đó bạn PHẢI có một tuyên bố trở lại nói những gì nên được giá trị khi trở về người gọi. Nếu bạn không làm như vậy và chỉ cần kết thúc hàm mà không trả về một giá trị, kết quả gọi hàm này là "Undefined Behavior" có nghĩa là chương trình của bạn có thể làm bất cứ điều gì (bao gồm cả treo hoặc xóa mọi thứ trên đĩa cứng của bạn).

Thông thường nếu giá trị chỉ là một int đơn giản, bạn sẽ nhận được số sôi nổi, nhưng trong các trường hợp phức tạp hơn có thể là một nguồn rắc rối lớn. Đừng làm thế.

Trình biên dịch thông thường sẽ thông báo cho bạn rằng bạn đã quên câu lệnh trả lại nếu được hướng dẫn đúng cách để làm như vậy (tức là bằng cách bật mức cảnh báo tối đa). Bạn có thể bỏ qua để trả lại giá trị chỉ cho các trường hợp mà hàm không thực sự trả lại (tức là ném một ngoại lệ hoặc vòng lặp mãi mãi).

1

Bạn cần lựa chọn giữa:

1) Chuyển qua tham chiếu/giá trị VÀ trả về INT.

2) Đi qua tham chiếu VÀ trả lại khoảng trống.

Lựa chọn này tùy thuộc vào mục đích của chức năng của bạn.

Nếu bạn muốn một hàm cung cấp cho bạn hình vuông của một số, hãy sử dụng số đầu tiên. Nếu bạn muốn một hàm nhận một biến và thay thế nó bằng hình vuông của nó, hãy dùng hàm thứ hai.

Vì vậy, một trong hai:

int sqr(int& x) 
{ 
    return x*x; 
} 

HOẶC

void sqr(int& x) 
{ 
    x= x*x; 
} 
Các vấn đề liên quan