下面是一個實例:html
#include <stdio.h>
struct Foo { char a; int b; double c; }foo1, foo2; //define two structs with three different fields void struct_assign(void) { foo2 = foo1; //structure directly assignment } int main() { foo1.a = 'a'; foo1.b = 1; foo1.c = 3.14; struct_assign(); printf("%c %d %lf\n", foo2.a, foo2.b, foo2.c); return 0; }
我在Ubuntu 13.04下使用gcc 4.7.3 編譯運行獲得的結果,以下所示:git
guohl@guohailin:~/Documents/c$ gcc struct_test1.c -o struct_test1
guohl@guohailin:~/Documents/c$ ./struct_test1 a 1 3.140000
能夠從結果上看出,結構體直接賦值在C語言下是可行的,咱們看看struct_assign()
函數的彙編實現,從而從底層看看C語言是如何實現兩個結構體之間的賦值操做的:github
struct_assign:
pushl %ebp movl %esp, %ebp movl foo1, %eax movl %eax, foo2 //copy the first 4 bytes from foo1 to foo2 movl foo1+4, %eax movl %eax, foo2+4 //copy the second 4 bytes from foo1 to foo2 movl foo1+8, %eax movl %eax, foo2+8 //copy the third 4 bytes from foo1 to foo2 movl foo1+12, %eax movl %eax, foo2+12 //copy the forth 4 bytes from foo1 to foo2 popl %ebp ret
這段彙編比較簡單,因爲結構體的對齊的特性,sizeof(srtruct Foo)=16
,經過四次movl
操做將foo1的結構體內容拷貝到結構體foo2中。從彙編上看出,結構體賦值,採用的相似於memcpy
這種形式,而不是逐個字段的拷貝。數組
若是結構體中含有其它複雜數據類型呢,例如數組、指針、結構體等,從上面的彙編實現能夠看出,只要兩個結構體類型相同,就能夠實現賦值,以下例:ide
#include <stdio.h>
struct Foo { int n; double d[2]; char *p_c; }foo1, foo2; int main() { char *c = (char *) malloc (4*sizeof(char)); c[0] = 'a'; c[1] = 'b'; c[2] = 'c'; c[3] = '\0'; foo1.n = 1; foo1.d[0] = 2; foo1.d[1] = 3; foo1.p_c = c; foo2 = foo1; //assign foo1 to foo2 printf("%d %lf %lf %s\n", foo2.n, foo2.d[0], foo2.d[1], foo2.p_c); return 0; }
運行結果以下:函數
guohl@guohailin:~/Documents/c$ gcc struct_test2.c -o struct_test2
guohl@guohailin:~/Documents/c$ ./struct_test2 1 2.000000 3.000000 abc
能夠看出結果和咱們想象的是同樣的。再次驗證結構體的賦值,是直接結構體的內存的拷貝!但正是這個問題,如上面的實例,foo1 和 foo2 中p_c 指針都是指向咱們申請的一塊大小爲4個字節的內存區域,這裏注意的是,結構體的拷貝只是淺拷貝,即指針p_c的賦值並不會致使再申請一塊內存區域,讓foo2的p_c指向它。那麼,若是釋放掉foo1中的p_c指向的內存,此時foo2中p_c變成野指針,這是對foo2的p_c操做就會出現一些不可預見的問題!在C++中引入了一種能夠容許用戶重載結構體賦值操做運算,那麼咱們就能夠根據語義重載賦值操做。spa
二等公民在維基百科上的解釋是:指針
二等公民不是一個正式的術語,用來描述一個社會體系內對一部分人的歧視或對外來人口的政治限制,即便他們做爲一個公民或合法居民的地位。 二等公民雖然不必定是奴隸或罪犯,但他們只享有有限的合法權利、公民權利和經濟機會,並常常受到虐待或忽視。法律無視二等公民,不向他們提供保護,甚至在制訂法律時可能會根本不考慮他們的利益。劃分出二等公民的行爲,廣泛被視爲一種侵犯人權的行爲。 典型的二等公民所面臨的障礙包括但不只限於(缺少或喪失表決權):權利被剝奪,限制民事或軍事服務(不包括任何狀況下的徵兵),以及限制,語言,宗教,教育,行動和結社的自由,武器的全部權,婚姻,性別認同和表達,住房和財產全部權 。code
從詞條上解釋能夠看出二等公民與一等公民在權利上是有差異的,這個詞頗有意思做爲計算機專業術語,其含義也有殊途同歸之妙!一樣咱們看看維基百科對計算機的術語」first-class citizen"(一等公民)的定義,通常要知足如下幾點,htm
對比着上面的定義來看C語言數組,數組做爲一個函數的參數傳遞時,退化成一個指針; 同時,數組沒法做爲函數的返回值; 也許讓數組更不服氣的是,數組之間不能直接賦值操做,以下面的操做就是非法的:
int a[10]; int b[10]; a = b;
可是若是數組包裝在結構體中,那麼就能進行賦值了!相比之下,結構體能夠做爲函數參數和返回值,這就是一等公民的待遇!至於爲何數組必須是二等公民,這是有歷史緣由的,你們能夠參考C 語言的發展史來看,有時間這塊內容我再補上!
參考資料: