[英]assign struct with char array inside using “=” works?
我正在審查某人的代碼,開發人員已將一個結構分配給另一個。 該struct包含一個char數組。 不知何故,“工作”,意味着結構A中的char數組確實被復制到結構B(而不是通過引用)。 我完全不知所措。 可以這樣向我解釋一下嗎? 我寫了一個小程序來說明“問題”。
#include <stdio.h>
#include <string.h>
/**************************************
* some define and typedef for later
**************************************/
#define MAX_LEN (80)
typedef struct month_s
{
char name[MAX_LEN];
} month_st;
/**************************************
* This bit is clear.
**************************************/
static void usingString()
{
char mCur[MAX_LEN] = {"Jan"};
char mNext[MAX_LEN] = {"Feb"};
/** this doesn't compile (of course) */
//mCur = mNext;
/** we need a pointer/reference */
char *pmCur = &mCur[0];
/** however now we "copy by reference"...*/
pmCur = &(mNext[0]);
/** ...so this change also applies to pmCur*/
strcpy(mNext, "Mar");
/** ...so pmCur is now "Mar"*/
printf("%s: %s\n", __func__, pmCur);
}
/**************************************
* I though the same/s.th. similar
* as above happens here. But this "works".
* I'm surprised to see that not to be
* the case. Can someone explain?
**************************************/
static void usingStruct()
{
month_st mCur = {"Jan"};
month_st mNext = {"Feb"};
/** I would have thought this is "copy by reference" for the string! */
mCur = mNext;
/** I would have thought this also overrides mCur.name
'cause it's pointing to mNext.name now */
strcpy(mNext.name, "Mar");
/** how come this works??? mCur.name is still "Feb"*/
printf("%s: %s\n", __func__, mCur.name);
}
/**************************************
* just the main()
**************************************/
int main()
{
usingString();
usingStruct();
return 0;
}
你可能最驚訝的是數組和指針在C中是不一樣的。在你的例子中的數組成員不僅包含指向字符串的指針而且包含字符串本身。 因此,當您將一個struct
實例分配給另一個struct
實例時,將復制所有這些。
根據你的結構聲明:
typedef struct month_s
{
char name[MAX_LEN];
} month_st;
sizeof(month_st)
包括作為結構成員的char數組的空格。(注意你正在進行靜態內存分配, name
不是指針而是數組)。
因此,當您將一個strct變量分配給其他變量時,它將完全復制數組(或者我們可以說總sizeof(month_st))
將被復制)。
接下來,您將聲明兩個結構變量:
month_st mCur = {"Jan"};
month_st mNext = {"Feb"};
變量mCur
和mNext
是不同的。 當你做任務時nCur = mNext;
, mNext
值復制到nCur
結構變量的內存,但兩者都有獨立的(自己的)內存。
strcpy()
語句:
strcpy(mNext, "Mar");
僅影響變量mNext
,它不會改變變量nCur
內容。
為了您的困惑,假設您已經按如下方式聲明了結構:
typedef struct month_s
{
char* name;
} month_st;
還是做nCur = mNext;
你將sizeof(month_st))
字節從mNext
到nCur
變量,因此只復制地址,因為name
是一個指向內存的指針。
在這種情況下,完整的數組/內存(您可能動態分配)不復制它稱為淺復制 。
你很困惑,因為你認為mCur
和mNext
是指向對象的指針,而實際上它們是對象。 struct month_s
僅在內存中分配空間以存儲月份名稱。 它沒有為存儲指向任何東西的指針分配內存。 因此,當mCur
被分配的值mNext
,整個對象,因為它是由值拷貝而不是通過參考復制。
為方便起見,我注釋了您的代碼:
static void usingStruct()
{
month_st mCur = {"Jan"};
month_st mNext = {"Feb"};
/** mCur and mNext are both objects. Assigning one to the other
* will copy by value and not by reference (as there is no reference
* to be copied in the first place). After this assignment,
* mCur == {"Feb"} */
mCur = mNext;
/** mNext.name is the address of the memory allocated to the object
* mNext. This line copies the characters "Mar" to the first three
* bytes of this memory allocation */
strcpy(mNext.name, "Mar");
/** At this point, mCur == {"Feb"} and mNext == {"Mar"} */
printf("%s: %s\n", __func__, mCur.name);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.