1

好的,我在这里搜索了其他名称相似的问题,但没有骰子。

我的问题:假设我们有一个结构和一个所述结构的数组:

typedef struct derp {
    int herp;
    double schlerp;
} struct_t;
struct_t* dynamic_array = (struct_t*)calloc(my_array_size, sizeof(struct_t));

结构是作为指针实现的吗?意思是,以下行为如何?

struct_t me;
me = dynamic_array[complicated calculation best not repeated];
me.herp += 2; //pretend it's properly initialized
me.schlerp *= 2; //ditto

该数组中的条目会显示结构成员的更改吗?即是me数组结构成员的深层副本,还是仅仅是指向数组所指向的相同成员的某种“指针”?

如果这个问题没有多大意义,我深表歉意,我试图用多种方式来表达它,以尽量减少误解。(希望这不会适得其反:P)

4

3 回答 3

3

me是数组中数据的拷贝。更改成员me不会改变数组中的内容。如果结构包含一个指针(char *例如 a ),那么它所指向的内容不会被复制,只是指针值,因此修改引用的指针也会影响数组条目的解除引用值(这有意义吗?)

于 2012-08-21T08:43:28.867 回答
2

它们不是作为指针实现的。

当您 []在指针上使用下标运算符时,它被解释为请求该位置的元素。因此编译器能够简单地确定偏移量,因为结构的大小是已知的/恒定的。

// creates a new struct on the stack:
struct_t me;
// copies from dynamic_array[idx] to me
me = dynamic_array[idx];

该数组中的条目会显示结构成员的更改吗?

不 -me是副本。

即 me 是数组结构成员的深层副本,还是仅仅是指向数组所指向的相同成员的某种“指针”?

如果你想改变原来的,你可以重新分配结构:

dynamic_array[idx] = me;

或者只是使用指向要变异的结构的指针:

struct_t* const me = &dynamic_array[idx];
me->herp += 2;
于 2012-08-21T08:40:50.283 回答
1

结构是编译器用来确定从结构开始的内存区域的开头到结构的各个成员的偏移量的描述或模板。

如果您使用结构创建单个非数组变量,编译器将为该变量分配内存。内存的大小将取决于结构的大小,而结构的大小又取决于结构成员的类型。

使用结构定义的数组是单个结构成员的数组。当您访问数组元素时,编译器会根据所使用的数组索引和结构的大小来计算内存偏移量。

结构的行为类似于 int 等内置类型。您可以声明一个 int 或一个结构,一个 int 或一个结构的数组,或者一个指向一个 int 或一个结构的指针。

int 和 struct 之间的主要区别在于 int 是内置类型,其中 struct 由程序员创建并描述为新类型。

然而,我发现将所有数据类型(内置或由程序员指定)视为内存区域的模板是最有帮助的,编译器使用它来跟上内存区域的地址,类型内存区域,内存区域的大小,内存区域允许哪些动作。

重要的一点是,当您在 C 中进行赋值时,将其视为一个内存区域到另一个内存区域的副本,除了使用memcpy()函数执行相同的内存复制之外没有任何智能。因此,当一个包含指针的结构变量分配给另一个结构变量时,两个结构变量将具有相同的指针,指向相同的内存区域。

然而,struc 和内置类型之间的赋值、指针计算和其他行为的基础非常相似。

typedef struct {
   int iValue;
   int jValue;
} MyStruct;

{
   int   iLoneInt, jLoneInt;
   int  *piLoneInt;
   MyStruct  aStruct, bStruct;
   MyStruct  *paStruct;

   // simple assignment
   iLoneInt = 1;
   aStruct.iValue = 1;    // specify the struct member

   // assignment of one variable to another
   bStruct = aStruct;    // copies the value in memory region aStruct to bStruct
   jLoneInt = iLoneInt;  // copies the value in memory region iLoneInt to jLoneInt
   memcpy (&bStruct, &aStruct, sizeof(MyStruct));  // same as assignment
   memcpy (&jLoneInt, &iLoneInt, sizeof(int));  // same as assignment

   piLoneInt = &iLoneInt;   // gets address of memory region iLoneInt
   paStruct = &aStruct;     // gets address of memory region aStruct

   jLoneInt = *piLoneInt;   // copies value in memory region pointed to by piLineInt to jLoneInt
   bStruct = *paStruct;    // copies value in memory region pointed to by paStruct to bStruct
   memcpy (&bStruct, paStruct, sizeof(MyStruct));  // same as assignment
于 2012-08-21T11:12:18.423 回答