C:结构是否作为指针实现?

时间:2012-08-21 08:37:24

标签: c arrays pointers struct

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

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

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)

3 个答案:

答案 0 :(得分:3)

me是数组中数据的副本。更改me中的成员不会改变数组中的内容。如果结构包含指针(例如char *),那么它指向的内容不会被复制,只会复制指针值,因此修改引用的指针也会影响数组条目的解引用值(这样做)感?)

答案 1 :(得分:2)

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

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

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

该数组中的条目是否会显示对struct成员的更改?

不 - me是副本。

  

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

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

dynamic_array[idx] = me;

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

struct_t* const me = &dynamic_array[idx];
me->herp += 2;

答案 2 :(得分:1)

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

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

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

struct具有类似于内置类型的行为,例如int。您可以声明一个int或一个struct,一个int或一个struct的数组,或一个指向int或struct的指针。

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

但是我发现,将程序员内置或指定的所有数据类型视为内存区域的模板是最有帮助的,编译器使用该模块来跟上内存区域的地址,内存区域的类型,内存区域的大小以及内存区域允许的操作。

重要的一点是,当您在C中进行赋值时,将其视为一个内存区域的副本,除了使用memcpy()函数执行相同的记忆副本。因此,当包含指针的struct变量分配给另一个struct变量时,两个struct变量将具有相同的指针,指向同一个内存区域。

然而,在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