2011-09-19 92 views
1

我寫了一段C代碼:結構值不能改變(C語言)

struct Res { 
    int a; 
    float b; 
    double c; 
}; 

struct Res ModRes(struct Res rrr) 
{ 
    rrr.a=222; 
    return rrr; 
} 

int main() 
{ 
    struct Res r[10]={1,2,3}; 
    ModRes(r[0]); 
    return 0; 
} 

爲什麼r[0]不是222 ModRes後?

回答

3

在C中,參數是按值傳遞的。你可以使函數接受一個struct Res *而非struct Res

struct Res *ModRes(struct Res *rrr) 
{ 
    rrr->a=222; 
    return rrr; 
} 

int main() 
{ 
    struct Res r[10]={1,2,3}; 
    ModRes(&r[0]); 
    return 0; 
} 
1

該結構體通過值(複製)傳遞給ModRes函數。所以原始值不會改變。

0

因爲您正在修改函數接收的本地副本作爲參數。關於指針的研究。

1

你宣佈ModRes()是由價值接受型水庫的結構,然後返回一個類型的RE的結構的功能。但是,當您從Main()調用ModRes()時,您已將Res類型的結構傳遞給它,但對ModRes()返回的結果沒有任何作用。所以,r [0] .a沒有改變。您需要將呼叫更改爲:

r[0] = ModRes(r[0]); 

使您的代碼正常工作。

但是,正如其他回覆的帖子所指出的,有更好的方法來實現你的目標。您需要更改ModRes,以便它可以通過引用而不是按值接受它的參數;也就是說,您需要將ModRes傳遞給r [0]結構。您的代碼應該是:

void ModRes(struct Res *rrr); // function prototype 

void ModRes(struct Res *rrr) // function definition 
{ 
    rrr->a=222; 
} 

,然後,在主():

ModRes(&r[0]); 

使用這種方法通常將遠遠小於由值傳遞的參數的一個字節生成的程序的數。該方法只需要將一個參數傳遞給ModRes:結構的地址。 ModRes然後通過該地址修改調用者的結構。它什麼也沒有返回,因爲修改已經完成。

其他方法將所有結構的內容複製到臨時存儲(通常是堆棧),並調用ModRes,然後修改該副本的元素a,將其更改爲222.然後,ModRes返回該副本(或副本該副本取決於您的編譯器)將其複製到臨時存儲區(通常是堆棧),然後返回給調用者,然後該調用者將該結構從堆棧複製回調用者的r [0]結構。