2012-07-09 21 views
6

Fonksiyon dönüş değeri üzerinde çalışmak için uncle '&' operatörünün hemen arkasındaki fonksiyonu uygulamak istedim. Ancak, ben (ben MinGW gelen gcc kullanın) derleme zamanı hatası alıyorumunary & operator işlevini kullanarak dönüş değeri

test.c: In function 'main':

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

Ben kolay sorum anlamak için yapmak için bir kod yaptı:

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

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

int function1() 
{ 
    return 10; 
} 

void function2(int *param) 
{ 
    return; 
} 

Bu kod aynı derleme zamanı hatası oluşturur .

soru şudur: Sadece İşlevsiz2 gelen '&' operatörünü kullanabilirsiniz nasıl "()", başka yerde başka bir kod olmadan?

+2

İşlev1 işlevi bir "int" döndürdüğü sürece yapamazsınız. – AnT

cevap

11

C99 ve daha sonra doğrudan elde edilebilir:

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

yani hazır bir bileşim yapmak fonksiyon dönüş değeri ihtiva etmektedir.

+0

Bu aslında oldukça zekice! Özünde geçici bir "anonim" değişken yapar ve onu işlev1'in dönüş değeri olarak başlatır. – eresonance

10

Yapamazsınız. Bir işlevin dönüş değeri, bir değerdir, ancak bir nesne değildir. Bellekte belirlenmiş bir adresi yok, adres yok ve bu yüzden ona bir işaretçi alamıyorsunuz. Bunun yerine yazabiliriz:

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

sorun & değişkenlerin adreslerini almasıdır. Bir fonksiyonun dönüş değeri zorunlu olarak hafızada saklanmaz. Diğer bir deyişle, bir lvalue değil (='un sol tarafına koyamazsınız). Bu nedenle, onun adresini sormak mantıklı değildir (çünkü mevcut değildir).

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

C11 standart olarak Madde 6.3.2.1'de lvalue tanımlar: Yine aynı standartta

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’’)

, diyor 6.5.3.2'de de:

Yapman gereken şudur

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

"Bir işlevin dönüş değeri mutlaka bir değişkende saklanmaz" ifadesinin yanlış olduğunu, özellikle "mutlaka gerekli değildir". Depolanacak iade edilen değer için bir değişken belirtmedikçe, saklanamaz. –

+0

@nathanwhite, haklısınız. Onu "hafıza" olarak değiştirdim. – Shahbaz

2

Bir işlev tarafından döndürülen bir değerin adresini alamıyorsunuz.

Bu değer bir CPU kaydı aracılığıyla arayana geri iletilirse ne olur?

function2() işlevini kullanmanın tek yolu, işlev1() işlevinin, bellekteki bir adrese sahip olan bir ara değişken kullanmasıdır.

main() 
{ 
    int a; 

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

Bunu doğrudan yapamazsınız. Fonksiyon dönüş değeri, yığında saklanabilir (ve kısa bir süre sonra başka bir işlev çağrısının üzerine yazılabilir) veya kayıt defterinde vb. (Çağrı kuralına bağlı olarak) olabilir.

Muhtemelen doğrudan bu yerlerden herhangi birine erişmek istemiyoruz ve hatta (aslında ne yaptığınızı biliyorum belki sürece, iyi) çok mantıklı değil.

Birlikte çalıştığınız bir işlevin dönüş değeri, bir rengin (iyi ... basit bir değer) iken, '&' operatörünün, derleyici çıktısında gördüğünüz gibi bir lvalue (atayabileceğiniz bir değer) olması gerekir.) için. Ergo, dönüş değerini bir değişkende ('ana()' inizin içindeki yerel bir değişkende saklayın, sonra adresi alın).istediğiniz ne

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