2012-05-21 35 views
5

Tôi rất mới lập trình và bối rối về khoảng trống, tôi biết rằng khi bạn đặt khoảng trống ở phía trước của hàm, điều đó có nghĩa là "nó không trả về gì cả" nhưng nếu hàm không trả về gì thì điểm viết là gì chức năng?? Dù sao, tôi đã nhận được câu hỏi này trên bài tập về nhà của tôi và đang cố gắng trả lời nó nhưng cần một số trợ giúp với khái niệm chung cùng với nó. bất kỳ sự giúp đỡ nào sẽ tuyệt vời, và hãy cố gắng tránh lingo kỹ thuật, tôi là một người mới nghiêm túc ở đây.nhầm lẫn về khoảng trống và ý nghĩa của nó.

Chức năng này thực hiện những gì?

void add2numbers(double a, double b) 
    { 
     double sum; 
     sum = a + b; 
    } 
+4

Có rất nhiều thứ để thực hiện chức năng, ngoài việc trả lại thứ gì đó ... –

+4

Bạn đang bỏ lỡ khái niệm về [_side effects_] (http://en.wikipedia.org/wiki/Side_effect_ (computer_science)). – ildjarn

+0

Chức năng đó không làm gì cả, và rất có thể sẽ bị xóa khi biên dịch –

Trả lời

3

Mục đích của một hàm khoảng trống là để đạt được một tác dụng phụ (ví dụ, sửa đổi một tham số tham chiếu hoặc một biến toàn cầu, thực hiện các cuộc gọi hệ thống như I/O, vv), không trả về một giá trị.

8
void ReturnsNothing() 
{ 
    cout << "Hello!"; 
} 

Như bạn thấy, chức năng này lợi nhuận gì cả, nhưng điều đó không có nghĩa là chức năng không gì.

Một hàm không có gì khác ngoài việc tái cấu trúc mã để đặt các thường trình thường được sử dụng cùng nhau. Nếu tôi đang in "Hello" thường xuyên, tôi đặt mã in "Hello" trong một hàm. Nếu tôi tính tổng của hai số, tôi sẽ đặt mã để làm điều đó và trả lại kết quả trong một hàm. Đó là tất cả về những gì bạn muốn.

+2

Tôi biết mọi người làm việc với Visual Basic (không phải VB.NET), và trong VB có sự khác biệt giữa chức năng và phụ. Đối với người phát triển trong vb sub là hàm trả về không có gì, và khi nó trả về một cái gì đó, nó là một hàm. Có thể nó gây nhầm lẫn cho một số người bắt đầu học C++ và các ngôn ngữ tương tự. –

1

Một hàm có giá trị trả về void có thể hữu ích cho các tác dụng phụ của nó. Ví dụ xem xét các chức năng thư viện chuẩn exit:

void exit(int status) 

Chức năng này không trả lại bất kỳ giá trị cho bạn, nhưng nó vẫn còn hữu ích cho tác dụng phụ của nó chấm dứt quá trình này.

1

Đó là chức năng đạt được gì - nhưng nếu bạn đã viết

void add2numbers(double a, double b, double &sum) 
{   
    sum = a + b; 
} 

Nó sẽ cung cấp cho bạn Tóm lại, cho dù đó là dễ dàng hơn để trả lại một giá trị hoặc sử dụng một tham số phụ thuộc vào chức năng

Thông thường bạn sẽ sử dụng một tham số nếu có nhiều kết quả nhưng giả sử bạn có một thói quen toán học trong đó câu trả lời có thể không thực hiện được.

bool sqrt(double value, double &answer) 
{ 
    if value < 0.0) { 
     return false; 
    } else { 
     answer = real_sqrt_function(value); 
     return true; 
    } 
} 
5

Có rất nhiều lý do để có khoảng trống chức năng, một số trong số này là có tác dụng phụ 'không tinh khiết':

int i=9; 
void f() { 
    ++i; 
} 

Trong trường hợp này i có thể là toàn cầu hoặc một thành viên lớp dữ liệu.

còn lại là hiệu ứng quan sát được

void f() { 
    std::cout <<"hello world" << std::endl; 
} 

Một chức năng khoảng trống có thể hoạt động trên một giá trị tham chiếu hoặc con trỏ.

void f(int& i) { 
    ++i; 
} 

Nó cũng có thể ném, mặc dù không làm điều này để kiểm soát luồng.

void f() { 
    while(is_not_broke()) { 
     //... 
    } 
    throw std::exception(); //it broke 
} 
1

Bạn đang ở bên phải - chức năng không thực hiện bất kỳ điều gì, vì nó tính toán thứ gì đó nhưng sau đó bị bỏ đi.

Hàm trả về void có thể hữu ích vì chúng có thể có "tác dụng phụ". Điều này có nghĩa là điều gì đó xảy ra không phải là đầu vào hoặc đầu ra của hàm. Ví dụ: nó có thể ghi vào một tập tin, hoặc gửi một email.

2

Việc sử dụng thuật ngữ chức năng trong ngữ cảnh C/C++ khá khó hiểu, vì nó không đồng ý với khái niệm toán học về hàm như "cái gì đó trả về giá trị". C/C++ gọi hàm trả về void tương ứng với khái niệm về thủ tục bằng các ngôn ngữ khác.

Sự khác biệt lớn giữa một hàm và thủ tục là một chức năng gọi là một biểu hiện , trong khi một cuộc gọi thủ tục là một tuyên bố Trong khi chức năng được gọi cho giá trị trả về của họ, các thủ tục được gọi cho tác dụng phụ của họ (chẳng hạn như sản lượng đầu ra, thay đổi trạng thái, v.v.).

1

Chức năng là một chút của một tên miền trong trường hợp này; có lẽ gọi nó là một phương pháp tốt hơn. Bạn có thể gọi một phương thức trên một đối tượng để thay đổi trạng thái của nó, tức là các giá trị của các trường của nó (hoặc các thuộc tính). Vì vậy, bạn có thể có một đối tượng với sự thích hợp cho các tọa độ x và y và một phương thức được gọi là Move lấy tham số xDelta và yDelta.

Gọi Di chuyển bằng 2, 3 sẽ khiến 2 được thêm vào thuộc tính X của bạn và 3 sẽ được thêm vào thuộc tính Y của bạn. Vì vậy, trạng thái của đối tượng đã thay đổi và nó sẽ không có ý nghĩa musch cho Move đã trả về một giá trị.

0

Tôi hiện đang sử dụng thư viện hình ảnh được gọi là VTK. Tôi thường viết các hàm void để cập nhật một số phần đồ họa được hiển thị trên màn hình. Tôi cũng sử dụng các hàm void để xử lý tương tác GUI trong Qt. Ví dụ, nếu bạn bấm vào một nút, một số văn bản được cập nhật trên GUI.

0

Bạn hoàn toàn đúng: tính toán hàm trả về không có gì là vô nghĩa - nếu bạn đang nói về các hàm toán học. Nhưng giống như với nhiều khái niệm toán học, "chức năng" có nhiều ngôn ngữ lập trình chỉ liên quan đến các hàm toán học, nhưng hành xử nhiều hay ít khác nhau một cách tinh tế.

Tôi tin rằng bạn nên giải thích bằng ngôn ngữ không làm sai: một ngôn ngữ như vậy là Haskell. Đó là một ngôn ngữ thuần túy chức năng có nghĩa là hàm Haskell cũng là một hàm toán học. Thật vậy, bạn có thể viết các hàm Haskell nhiều hơn theo kiểu toán học, ví dụ:

my_tan(x) = sin(x)/cos(x)   -- or (preferred): tan' x = sin x/cos x 

hơn trong C++

double my_tan(double x) { return sin(x)/cos(x); } 

Tuy nhiên, trong chương trình máy tính bạn không chỉ muốn tính toán chức năng, phải không? Bạn cũng muốn hoàn thành công việc, như hiển thị nội dung trên màn hình, gửi dữ liệu qua mạng, đọc giá trị từ cảm biến, v.v. Trong Haskell, những thứ như thế này được tách biệt hoàn toàn với chức năng thuần túy, tất cả đều hoạt động trong cái gọi là IO đơn nguyên. Ví dụ, hàm putStrLn, in một dòng ký tự, có loại String -> IO().Ý nghĩa, phải mất một đối số String và trả về hành động IO in ra chuỗi đó khi được gọi từ hàm main và không có gì khác (số () parens gần bằng void trong C++). Cách làm IO này có nhiều lợi ích, nhưng hầu hết các ngôn ngữ lập trình đều cẩu thả: chúng cho phép tất cả các chức năng để làm IO, và cũng để thay đổi trạng thái bên trong của chương trình của bạn. Vì vậy, trong C++, bạn có thể chỉ cần có một hàm void putStrLn(std::string), mà còn "trả về" một hành động IO in chuỗi và không có gì khác, nhưng không rõ ràng cho bạn biết như vậy. Lợi ích là bạn không cần phải buộc nhiều nút thắt trong não của bạn khi suy nghĩ về những gì các đơn nguyên IO thực sự là (nó khá vòng xoay). Ngoài ra, nhiều thuật toán có thể được triển khai để chạy nhanh hơn nếu bạn có khả năng thực sự nói với máy "thực hiện chuỗi các quy trình này ngay bây giờ!" thay vì chỉ yêu cầu kết quả của một số tính toán trong đơn nguyên IO.