2010-02-20 38 views
109

您可以將結構的一個實例分配給另一個,就像這樣:分配一個結構到另一個用C

struct Test t1; 
struct Test t2; 
t2 = t1; 

我已經看到它的結構簡單工作,BU它對於複雜結構的工作?
編譯器如何知道如何複製數據項取決於它們的類型,即區分int和字符串?

回答

107

是的,如果結構是相同的類型。認爲它是一個內存拷貝。

+56

請記住,沒有深度複製,指向內存不會被複制。 –

+2

併發性也是一個問題。 –

+12

@Tim併發比它是內置的類型,如整數和雙打的任務不再是一個問題 - 分配不爲這些原子操作要麼。 – 2010-02-20 13:58:29

108

是的,結構支持賦值。不過,也有問題:

struct S { 
    char * p; 
}; 

struct S s1, s2; 
s1.p = malloc(100); 
s2 = s1; 

現在,這兩個結構的指針指向相同的內存塊 - 編譯器不尖的複製數據。現在很難知道哪個結構實例擁有數據。這就是爲什麼C++發明了用戶可定義的賦值運算符的概念 - 您可以編寫特定的代碼來處理這種情況。

+1

我調升,因爲讀它讓我實現我自己的答案錯誤/遺漏。 – Clifford

+1

+1注意到實際上沒有任何複製正在進行。 –

+11

爲什麼這被標記爲垃圾郵件?有人失去對鼠標的控制權嗎? –

13

這是一個簡單的副本,就像你對memcpy()所做的一樣(事實上,一些編譯器實際上會爲該代碼產生一個針對memcpy()的調用)。 C中沒有「字符串」,只有指向字符串的指針。如果你的源碼結構包含這樣一個指針,那麼指針會被複制,而不是字符本身。

4

您的意思是「複雜」,如複數中的實部和虛部?這看起來不太可能,所以如果不是的話,你必須舉一個例子,因爲「複雜」在C語言方面沒有任何具體含義。

您將獲得該結構的直接內存副本;這是否是你想要的取決於結構。例如,如果結構包含指針,則這兩個副本將指向相同的數據。這可能是也可能不是你想要的;這是你的程序設計。

要執行「智能」副本(或「深層」副本),您需要實現一個功能來執行副本。如果結構本身包含也包含指針的指針和結構,並且可能指向這些結構的指針(可能這就是「複雜」的含義),這很難實現,並且很難維護。簡單的解決方案是使用C++併爲每個結構或類實現複製構造函數和賦值運算符,然後每個負責自己的複製語義,可以使用賦值語法,並且更容易維護。

19

在這個例子中首先查找:

爲一個簡單的C程序的C代碼如下

struct Foo { 
    char a; 
    int b; 
    double c; 
    } foo1,foo2; 

void foo_assign(void) 
{ 
    foo1 = foo2; 
} 
int main(/*char *argv[],int argc*/) 
{ 
    foo_assign(); 
return 0; 
} 

等效ASM代碼給出foo_assign()是

00401050 <_foo_assign>: 
    401050: 55      push %ebp 
    401051: 89 e5     mov %esp,%ebp 
    401053: a1 20 20 40 00   mov 0x402020,%eax 
    401058: a3 30 20 40 00   mov %eax,0x402030 
    40105d: a1 24 20 40 00   mov 0x402024,%eax 
    401062: a3 34 20 40 00   mov %eax,0x402034 
    401067: a1 28 20 40 00   mov 0x402028,%eax 
    40106c: a3 38 20 40 00   mov %eax,0x402038 
    401071: a1 2c 20 40 00   mov 0x40202c,%eax 
    401076: a3 3c 20 40 00   mov %eax,0x40203c 
    40107b: 5d      pop %ebp 
    40107c: c3      ret  

正如你所看到的,一個賦值僅僅被彙編中的「mov」指令替代bly,賦值操作符僅僅意味着將數據從一個存儲位置移動到另一個存儲位置。 該賦值只對結構的直接成員執行,並且在結構中具有複雜數據類型時將無法複製。這裏COMPLEX意味着你不能有指向數組的指針。

結構內的字符數組本身將不會對大多數編譯器工作,這是因爲分配將只是一味看也不看的數據類型爲複合型的複製。

+0

u能詳細闡述其條件導致它似乎爲我工作,它會失敗總是 –