2012-07-09 13 views
6

Tôi muốn áp dụng toán tử '&' đơn giản ngay sau hàm để hoạt động trên giá trị trả về hàm. Tuy nhiên, tôi nhận được một lỗi thời gian biên dịch (tôi sử dụng gcc từ MinGW)sử dụng đơn vị & toán tử trên giá trị trả về hàm

test.c: In function 'main':

test.c:8:12: error: lvalue required as unary '&' operand

tôi đã thực hiện một mã số để làm cho câu hỏi của tôi dễ dàng hơn để hiểu:

int function(); 
void function2(int *param); 

main() 
{ 
    function2(&function1()); 
} 

int function1() 
{ 
    return 10; 
} 

void function2(int *param) 
{ 
    return; 
} 

Mã này tạo ra cùng một lỗi thời gian biên dịch .

Câu hỏi đặt ra là: Tôi có thể sử dụng toán tử '&' chỉ từ hàm2 "()", không có mã khác ở đâu?

+2

Bạn không thể, miễn là 'hàm1' trả về' int'. – AnT

Trả lời

11

gì bạn muốn có thể đạt được trong C99 và sau đó qua:

function2((int[]){function1()}); 

ví dụ: thực hiện một hợp chất đen có chứa các giá trị hàm trả lại.

+0

Điều này thực sự khá thông minh! Về bản chất tạo ra một biến "ẩn danh" tạm thời và khởi tạo nó thành giá trị trả về của hàm1. – eresonance

10

Bạn không thể. Giá trị trả về của một hàm là một giá trị nhưng không phải là một đối tượng. Nó không có vị trí được chỉ định trong bộ nhớ, không có địa chỉ, và do đó bạn không thể lấy một con trỏ đến nó. Thay vào đó bạn có thể viết:

int a = function1(); 
function2(&a); 
3

Vấn đề là & lấy địa chỉ của các biến. Giá trị trả về của một hàm không nhất thiết được lưu trữ trong bộ nhớ. Nói cách khác, nó không phải là lvalue (bạn không thể đặt nó ở bên trái của =). Do đó, nó không có ý nghĩa để yêu cầu địa chỉ của nó (vì nó không tồn tại).

Những gì bạn cần làm là như sau:

int result = function1(); 
function2(&result); 

Tiêu chuẩn C11 xác định lvalue trong 6.3.2.1 như:

An lvalue is an expression (with an object type other than void) that potentially designates an object; (footnote: The name ‘‘lvalue’’ comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object ‘‘locator value’’. What is sometimes called ‘‘rvalue’’ is in this International Standard described as the ‘‘value of an expression’’)

Trong cùng một tiêu chuẩn, trong 6.5.3.2 nó nói:

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

+0

Ghi rõ "Giá trị trả về của hàm không nhất thiết được lưu trữ trong một biến" là không chính xác, cụ thể là "không nhất thiết". Trừ khi bạn chỉ định một biến cho giá trị trả về được lưu trữ, nó không được lưu trữ. –

+0

@nathanwhite, bạn nói đúng. Tôi đã đổi nó thành "bộ nhớ". – Shahbaz

2

Bạn không thể lấy địa chỉ của một giá trị được hàm trả về.

Điều gì xảy ra nếu giá trị đó được chuyển lại cho người gọi qua thanh ghi CPU?

Cách duy nhất để thực hiện hàm 2() sử dụng kết quả của hàm 1() là sử dụng biến số trung gian, xảy ra có địa chỉ trong bộ nhớ.

main() 
{ 
    int a; 

    a = function1(); 
    function2(&a); 
} 
1

Bạn không thể thực hiện việc này trực tiếp. Giá trị trả về hàm có thể được lưu trữ trên ngăn xếp (và sẽ sớm bị ghi đè trong một cuộc gọi hàm khác), hoặc có thể trong sổ đăng ký, vv (tùy thuộc vào quy ước gọi).

Bạn có thể không muốn truy cập trực tiếp vào bất kỳ địa điểm nào và thậm chí không có ý nghĩa nhiều (tốt, có thể trừ khi bạn thực sự biết mình đang làm gì).

Giá trị trả về của hàm bạn làm việc là giá trị (cũng ... chỉ đơn giản là giá trị), trong khi toán tử '&' như bạn đã thấy trong đầu ra trình biên dịch, một giá trị đến). Ergo, chỉ lưu trữ giá trị trả về trong một biến (một biến cục bộ bên trong 'main()' của bạn, sau đó lấy địa chỉ của nó).

int main() { 
    int x = function1(); 
    function2(&x); 
}