Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用“指定结构,内部包含字符数组”=&引用;作品_C_Arrays_Struct_Char - Fatal编程技术网

C 使用“指定结构,内部包含字符数组”=&引用;作品

C 使用“指定结构,内部包含字符数组”=&引用;作品,c,arrays,struct,char,C,Arrays,Struct,Char,我正在检查某人的代码,开发人员已将一个结构分配给另一个结构。结构包含一个字符数组。不知何故,这“起作用”,意味着结构A中的字符数组确实被复制到结构B(不是通过引用)。我完全困惑不解。s.o.能给我解释一下吗?我写了一个小程序来说明这个“问题” #包括 #包括 /************************************** *有些定义和类型定义供以后使用 **************************************/ #定义最大长度(80) typedef结构月 {

我正在检查某人的代码,开发人员已将一个结构分配给另一个结构。结构包含一个字符数组。不知何故,这“起作用”,意味着结构A中的字符数组确实被复制到结构B(不是通过引用)。我完全困惑不解。s.o.能给我解释一下吗?我写了一个小程序来说明这个“问题”

#包括
#包括
/**************************************
*有些定义和类型定义供以后使用
**************************************/
#定义最大长度(80)
typedef结构月
{
字符名[MAX_LEN];
}月;;
/**************************************
*这一点很清楚。
**************************************/
使用字符串()的静态void
{
char mCur[MAX_LEN]={“Jan”};
char mNext[MAX_LEN]={“Feb”};
/**这不编译(当然)*/
//mCur=mNext;
/**我们需要一个指针/引用*/
char*pmCur=&mCur[0];
/**但现在我们“参照复制”*/
pmCur=&(mNext[0]);
/**…因此此更改也适用于pmCur*/
strcpy(mNext,“Mar”);
/**…所以pmCur现在是“Mar”*/
printf(“%s:%s\n”,函数,pmCur);
}
/**************************************
*我想是一样的。类似的
*就像上面发生的一样。但这“有效”。
*我很惊讶地看到这不是事实
*这个案子。有人能解释一下吗?
**************************************/
使用struct()的静态void
{
月份{“一月”};
第二个月{“二月”};
/**我本以为这是字符串的“引用复制”*/
mCur=mNext;
/**我本以为这也会覆盖mCur.name
因为它现在指向mNext.name*/
strcpy(mNext.name,“Mar”);
/**这是怎么回事???mCur.name仍然是“Feb”*/
printf(“%s:%s\n”,函数名,mCur.name);
}
/**************************************
*只是主要的
**************************************/
int main()
{
使用字符串();
使用struct();
返回0;
}

您可能最惊讶的是,数组和指针在C语言中不是一回事。在您的示例中,数组成员不仅包含指向字符串的指针,还包含字符串本身。因此,当您将一个
struct
实例分配给另一个实例时,所有这些都会被复制。

根据您的struct声明:

typedef struct month_s
{
    char name[MAX_LEN];
} month_st;
sizeof(month\u st)
包括作为结构成员的char数组的空格。(注意,您正在进行静态内存分配,
name
不是指针而是数组)。
所以,当您将一个strct变量分配给另一个变量时,它会完全复制数组(或者我们可以说total
sizeof(month_st))
bytes将被复制)

接下来,您将声明两个结构变量:

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
是指向对象的指针,而实际上它们是对象。结构
month\u 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);
}

关于指针和数组之间的区别,我看到了三种解释,但据我所知,它们似乎没有解决所提出的问题

据我所知,问题是:“我知道我不能将一个数组分配给另一个数组,所以如果数组位于结构中,为什么我可以这样做?”

答案基本上是“因为语言是这样说的”。尽管结构是聚合类型,并且很可能包含数组,但语言规范说结构是可分配的,因此结构是可分配的。这是第6.5.16.1节和中的简单赋值

(在后台,编译器可能必须实现内存拷贝,但这是编译器的问题,不是你的问题。)

没有卷影拷贝,而是浅拷贝。
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);
}