您可以將結構的一個實例分配給另一個,就像這樣:分配一個結構到另一個用C
struct Test t1;
struct Test t2;
t2 = t1;
我已經看到它的結構簡單工作,BU它對於複雜結構的工作?
編譯器如何知道如何複製數據項取決於它們的類型,即區分int
和字符串?
您可以將結構的一個實例分配給另一個,就像這樣:分配一個結構到另一個用C
struct Test t1;
struct Test t2;
t2 = t1;
我已經看到它的結構簡單工作,BU它對於複雜結構的工作?
編譯器如何知道如何複製數據項取決於它們的類型,即區分int
和字符串?
是的,如果結構是相同的類型。認爲它是一個內存拷貝。
是的,結構支持賦值。不過,也有問題:
struct S {
char * p;
};
struct S s1, s2;
s1.p = malloc(100);
s2 = s1;
現在,這兩個結構的指針指向相同的內存塊 - 編譯器不尖的複製數據。現在很難知道哪個結構實例擁有數據。這就是爲什麼C++發明了用戶可定義的賦值運算符的概念 - 您可以編寫特定的代碼來處理這種情況。
這是一個簡單的副本,就像你對memcpy()
所做的一樣(事實上,一些編譯器實際上會爲該代碼產生一個針對memcpy()
的調用)。 C中沒有「字符串」,只有指向字符串的指針。如果你的源碼結構包含這樣一個指針,那麼指針會被複制,而不是字符本身。
您的意思是「複雜」,如複數中的實部和虛部?這看起來不太可能,所以如果不是的話,你必須舉一個例子,因爲「複雜」在C語言方面沒有任何具體含義。
您將獲得該結構的直接內存副本;這是否是你想要的取決於結構。例如,如果結構包含指針,則這兩個副本將指向相同的數據。這可能是也可能不是你想要的;這是你的程序設計。
要執行「智能」副本(或「深層」副本),您需要實現一個功能來執行副本。如果結構本身包含也包含指針的指針和結構,並且可能指向這些結構的指針(可能這就是「複雜」的含義),這很難實現,並且很難維護。簡單的解決方案是使用C++併爲每個結構或類實現複製構造函數和賦值運算符,然後每個負責自己的複製語義,可以使用賦值語法,並且更容易維護。
在這個例子中首先查找:
爲一個簡單的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意味着你不能有指向數組的指針。
結構內的字符數組本身將不會對大多數編譯器工作,這是因爲分配將只是一味看也不看的數據類型爲複合型的複製。
u能詳細闡述其條件導致它似乎爲我工作,它會失敗總是 –
請記住,沒有深度複製,指向內存不會被複制。 –
併發性也是一個問題。 –
@Tim併發比它是內置的類型,如整數和雙打的任務不再是一個問題 - 分配不爲這些原子操作要麼。 – 2010-02-20 13:58:29