0

在 C 中,以下是合法的:

int a[] = {27,2};
int *b;
int c;

b = a;
c = *b; /* c == 27 */

关键是 a 只是数组的地址,所以我可以将它分配给一个指针。为什么结构不一样,我会假设结构变量的值只是地址,因此我应该能够将它分配给指针,如下所示:

struct foo bar;
struct foo *doo;
bar.x = 0;
doo = bar; //is this legal?
doo.x = 0; //why can't I use the dot?

换句话说,如果结构变量的值只是第一个组件的地址(我想这是像数组一样的情况),上面的代码应该是合法的。

4

6 回答 6

3

关键是这a只是数组的地址,所以我可以将它分配给一个指针。

这不太对:编译器数组的名称转换为指向数组初始元素的指针。这会自动发生,而不需要强制转换或操作员的“地址” &。但是,a不仅仅是地址,这可以通过将其大小与sizeof(a).

这应该可以解释为什么struct对于数组而言并非如此(即,数组并非如此)。对于structs,“地址”运算符&是强制性的:

doo = &bar;

doo.x = 0; //为什么我不能使用点?

C 通过指针访问structs 元素的语法不同:您需要使用->运算符而不是点.运算符。

于 2013-02-12T21:24:39.160 回答
2

正如其他人指出的那样,数组的语义与结构的语义不同。至于为什么会这样,您必须记住 C 源自早期语言(BCPLB),这两种语言都是“无类型”语言,将内存视为固定长度“单词”或“单元格”的线性数组. 在那些较旧的语言中,当您声明一个数组时

auto V[10]; 

留出11个记忆单元;一个用于名为 的对象V,然后再有 10 个用于数组元素;数组的第一个元素的地址存储在V.

来自 Dennis Ritchie 的论文The Development of the C Language

当我尝试扩展类型表示法,尤其是添加结构化(记录)类型时,问题变得很明显。结构似乎应该以直观的方式映射到机器的内存中,但是在包含数组的结构中,没有好地方来存储包含数组基数的指针,也没有任何方便的方法来安排它初始化。例如,早期 Unix 系统的目录条目可能在 C 中描述为

结构{
    整数;
    字符名称[14];
};
我希望该结构不仅可以表征抽象对象,还可以描述可能从目录中读取的位集合。编译器可以在哪里隐藏语义要求的名称指针?即使结构被认为更抽象,并且指针的空间可以以某种方式隐藏,我如何处理在分配复杂对象时正确初始化这些指针的技术问题,也许是一个指定结构包含包含任意深度结构的数组的结构?

该解决方案构成了无类型 BCPL 和类型 C 之间进化链中的关键跳跃。它消除了存储中指针的具体化,而是在表达式中提到数组名称时导致创建指针。在今天的 C 语言中仍然存在的规则是,当数组类型的值出现在表达式中时,它们会被转换为指向组成数组的第一个对象的指针。

强调我的。这就是为什么 C 中的数组表达式与所有其他表达式类型(包括结构类型)的处理方式不同。

于 2013-02-12T23:22:50.250 回答
1

斗=酒吧;//这合法吗?

不,试试:

doo = & bar;
     ^^

doo.x = 0; //为什么我不能使用点?

因为doo是指针。尝试:

doo->x = 0;
   ^^
于 2013-02-12T21:23:58.973 回答
1

不,这不对。你想做的是:

doo = &bar; 
doo->x = 0;

在数组的情况下它可以工作,因为数组T可以隐式转换为T*,但对于结构则不是这样。一个指针可以存储你的 struct objext ( &bar) 的地址。为了使用指针间接访问结构元素,应该使用 -> 运算符。a->b相当于(*a).b

于 2013-02-12T21:24:13.560 回答
1
  doo = bar; //is this legal?

不,它无效。左操作数是结构类型,右操作数是指针类型。

这是合法的:

 doo = &bar;

&bar是指向的类型指针struct foo

现在:

  doo.x = 0; //why can't I use the dot?

因为操作数必须是结构类型,但它是指针类型。用于->从指向结构类型的指针的对象中访问元素。

  doo->x = 0;  // this is valid
于 2013-02-12T21:24:15.907 回答
1

不,结构的值是结构本身,而不是它的地址。这使您可以执行以下操作:

struct foo a;
struct foo b;
b = a;  /* this does a memberwise copy of all fields from a to b */

如果您想要结构的地址,请使用&运算符:

struct foo a;
struct foo* b = &a
struct foo c;
c = *b;  /* this does a memberwise copy of all fields from a to c */
于 2013-02-12T21:26:27.200 回答