2009-08-18 33 views
28

我試圖找出結構究竟是'是'並且遇到問題,所以我真的有兩個問題:結構中的char數組不兼容嗎?

1)'sara'中保存了什麼?它是一個指向結構的第一個元素的指針嗎?

2)更有趣的問題:爲什麼不把它編譯? GCC說「test.c的:10:錯誤:不兼容的類型分配」,我想不通爲什麼...

#include <stdio.h> 

struct name { 
    char first[20]; 
    char last[20]; 
}; 

int main() { 
    struct name sara; 
    sara.first = "Sara"; 
    sara.last = "Black"; 
    printf("struct direct: %x\n",sara); 

    printf("struct deref: %x\t%s\n", *sara, *sara); 


} 

(這部分已經解決了你的答案已經,太棒了!)謝謝你的幫助!

+0

這裏其實是一個充滿欺騙:http://stackoverflow.com/questions/1265117/structure-problem-in-c/ – sharptooth 2009-08-18 08:42:45

+1

噢。但我確實搜索過:D – Patrick 2009-08-18 08:44:53

回答

51

這有沒有關係結構 - 在C數組是不可轉讓的:

char a[20]; 
a = "foo"; // error 

你需要使用的strcpy:

strcpy(a, "foo"); 

或代碼:

strcpy(sara.first, "Sara"); 
+4

+1對於'strcpy' over'strncpy' ... :) – GManNickG 2009-08-18 08:49:16

+0

我會先用char * sara.first =「Sara」,因爲我只在需要時使用固定大小的數組; 這是一個好的或壞的做法(在C中,而不是C++)? – gramm 2009-08-18 09:06:31

+1

@gramm如果你這樣做,你正在承諾自己動態內存管理,這可能不是必要的或可取的。 – 2009-08-18 09:55:18

4

使用strncpy以確保您沒有緩衝區溢出。

char name[]= "whatever_you_want"; 
strncpy(sara.first, name, sizeof(sara.first)-1); 
sara.first[sizeof(sara.first)-1] = 0; 
+1

這假定靜靜地截斷數據不會導致程序在其他地方失敗。通常顯式處理字符串不適合緩衝區的情況比通過strcpy調用未定義的行爲更好,或者使用strncpy將程序置於意外狀態。但是我推論 - 如果程序的其餘部分佔用了無聲截斷(例如,從不期望sara.first將匹配「whatever_you_want」),那麼程序狀態並非意外。 – 2009-08-18 11:17:23

+1

@onebyone此行爲必須在合同中記錄。 – TimW 2009-08-18 11:31:24

+0

如果這足夠了,那麼爲什麼不直接說明輸入字符串不能超過結構可以應付的呢?這個問題是設計API幫助客戶避免錯誤的問題之一。國際海事組織,默默地忽略什麼可能是一個錯誤不這樣做。但正如我所說,我在概括,這可能不是一個錯誤。如果該函數被稱爲「StoreFirst20CharsOf」,那麼我們可以合理地假設任何人看着調用代碼都會明白它的作用。所以strncpy有幾個用途。 – 2009-08-18 11:35:20

2

sara是結構本身,而不是一個指針(即,其中實際結構數據被存儲在棧上的變量表示的位置)。因此,*sara是沒有意義的,不會編譯。

+0

啊,好的...謝謝 – Patrick 2009-08-18 09:13:26

0

薩拉結構是包含內的變量的存儲塊。有近一個經典的聲明沒有區別:和結構

char first[20]; 
int age; 

struct Person{ 
char first[20]; 
int age; 
}; 

在這兩種情況下,你只是分配更多的內存來存儲變量,並在這兩個情況下,會有20 +4字節保留。在你的情況下,Sara只是一個2x20字節的內存塊。

唯一的區別是,一個結構,分配內存爲單塊,所以如果你把薩拉的起始地址和跳20個字節,你會發現「最後一個」變量。有時這可能很有用。

檢查http://publications.gbdirect.co.uk/c_book/chapter6/structures.html更多:)。

+0

Sara是*至少* 2 * 20字節的內存塊。它可能更多,如果有填充。 – caf 2009-08-18 09:23:32

+0

而'offsetof(struct name,last)'不一定是20,或者(雖然它幾乎肯定是)。 – caf 2009-08-18 09:24:35

+0

不知道。指定可變大小時是否有填充的可能性?例如, unsigned char速度:7; 無符號字符標誌:3; 等...我在工作中使用它,從來沒有填充和數據對齊的問題。 – gramm 2009-08-18 09:32:49

3

您也可以初始化它像這樣:

struct name sara = { "Sara", "Black" }; 

因爲(作爲特殊情況)你被允許從初始化字符串常量字符數組。

現在,至於什麼是結構實際上是 - 這是其他值組成的複合型。什麼sara實際上看起來像在存儲器是(20個連續的炭值的塊,其可以被稱爲使用sara.first,接着0或更多的填充字節,其後爲20個連續的char值的另一個塊(其可被稱爲使用sara.last) 。struct name類型的所有其他實例都以相同的方式進行佈局。

在這種情況下,這是不太可能有任何填充,所以struct name僅僅是一個40個字符,而您的前20有一個名字和塊中的最後20

你可以找出struct name使用sizeof(struct name)得到的內存塊有多大,並且您可以找出該內存塊中每個結構的成員使用offsetof(struct name, first)offsetof(struct name, last)的位置。

8

或者你可以只使用動態分配,例如:

struct name { 
    char *first; 
    char *last; 
}; 

struct name sara; 
sara.first = "Sara"; 
sara.last = "Black"; 
printf("first: %s, last: %s\n", sara.first, sara.last); 
0

可以使用的strcpy來填充它。您也可以從另一個結構初始化它。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

struct name { 
    char first[20]; 
    char last[20]; 
}; 

int main() { 
    struct name sara; 
    struct name other; 

    strcpy(sara.first,"Sara"); 
    strcpy(sara.last, "Black"); 

    other = sara; 

    printf("struct: %s\t%s\n", sara.first, sara.last); 
    printf("other struct: %s\t%s\n", other.first, other.last); 

} 
相關問題