使用“=”在内部分配带有char数组的结构?
Posted
技术标签:
【中文标题】使用“=”在内部分配带有char数组的结构?【英文标题】:assign struct with char array inside using "=" works? 【发布时间】:2013-07-27 16:27:49 【问题描述】:我正在审查某人的代码,而开发人员已将一个结构分配给另一个结构。该结构包含一个 char 数组。不知何故,“工作”,这意味着来自 struct A 的 char 数组确实被复制到 struct 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;
【问题讨论】:
【参考方案1】:我看到了关于指针和数组之间区别的三种解释,但据我所知,它们似乎没有解决所提出的问题。
据我所知,问题是:“我知道我不能将一个数组分配给另一个数组,那么为什么 可以 如果数组在结构中,我可以这样做?”
答案基本上是“因为语言是这样说的”。尽管结构是聚合类型,并且很可能包含数组,但语言规范说结构是可分配的,因此结构是可分配的。这是N1256 和N1570 中的6.5.16.1 Simple assignment
部分。
(在后台,编译器可能必须实现内存副本,但这是编译器的问题,而不是你的问题。)
【讨论】:
【参考方案2】:您可能最惊讶的是,数组和指针在 C 中不是一回事。在您的示例中,数组成员不仅包含指向字符串的指针,还包含字符串本身。因此,当您将一个 struct
实例分配给另一个实例时,所有这些都会被复制。
【讨论】:
【参考方案3】:根据你的结构声明:
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
的地址是指向内存的指针。
在这种情况下,完整的数组/内存(您可能会动态分配)不复制这称为浅复制。
【讨论】:
没有Shadow Copy有Shallow Copy。【参考方案4】:您很困惑,因为您认为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);
【讨论】:
以上是关于使用“=”在内部分配带有char数组的结构?的主要内容,如果未能解决你的问题,请参考以下文章
在内部使用带有 UIWebView 的 url 方案来更改 UILabel