首先C:勘误?指针语法



我正在教自己C编程,使用O'Reilly出版的" Head First C"。(此外,还有其他几本文本。(

在第58页上的示例节目中,我在这本书的指针介绍中非常挂起。给我扔的是文字中有点呼唤,指向这条线:

int *choice = contestants;

呼叫读数:

"选择"现在是"参赛者"数组的地址。

,据我所知,这是错误的。该行将*choice分配给存储为contestants数组的 value ,不是吗?免责声明:我现在无法访问本书/章节。

考虑contestants是数组类型,引用C11,第§6.3.2.1章(强调矿山((

除非是sizeof操作员的操作数,_Alignof操作员或 Unary &操作员,或者是用于初始化数组的字符串,表达式具有 类型''type'数组'被转换为带有类型'指针的'指点'的表达式 对于数组对象的初始元素,而不是lvalue。[...]

在您的情况下,数组变量用作分配运算符的RHS,因此在这种情况下,contestants&(contestants[0])相同。

这是int *完全相同的类型,它是要分配的变量的相同类型(LHS(。

,因此您已经有四个答案,但他们都没有提到 sigitionment 初始化语法之间的区别语法。

int *choice = contestants;  // initialization

以上等效于此:

int *choice;                // declaration
choice = contestants;       // assignment to pointer

,但与此完全不同(在初始化中无法完成(:

int *choice;                // declaration
*choice = contestants;      // assignment to target (not valid unless choice is initialized)

第二版本不正确,因为它试图将contestants的值存储在choice指向的地址上 - 但是choice不包含地址,除非您初始化。取消可能的统一指针始终是一个错误。

这本书是正确的。指针的工作方式与变量不同, *在不同情况下的工作方式不同。

开始,您可能知道指针只是一个变量,该变量包含位置的地址,以存储另一个项目

我们使用 int *choice我们创建一个指向整数的指针,该密码存储整数的地址

在这种情况下,我假设参赛者是一个数组。我们假设这是一个ints

int contestants[5] = [0,1,2,3,4];

集合(例如数组(总是存储为指向第一个元素的指针。因此,第二个元素是addressof_first_item + sizeof(element_stored)

让我们假设地址是0x12345,就像此int contestants = 0x12345

现在我们选择了该地址: int *choice = contestants

换句话说,这是通往整数的指针,恰好是参赛者数组中的第一个元素。

作为旁注,我们也可以将其写为:

int* choice = &contestants[0];

*操作员的另一个用例在指针方面是删除。提取涉及将值在指向指向的地址上获取值。

int value = *choice;

将为我们提供一个值为0的整数,因为地址存储到第一个元素

您可能不知道的是数组的名称是该数组的第一个元素上的指针。示例

int contestants[] = {1, 2, 3};

表示&contestants[0]具有与contestants

的值相同的值列表。

  • 一个数组变量可以用作指针。
  • 数组变量指向数组中的第一个元素。

以及在标有指针decay 的框中进一步向下。

由于数组变量与指针变量略有不同,因此当将数组分配给指针时,您需要小心。如果将数组分配给指针变量,则指针变量仅包含数组的地址。

严格来说,这本书不正确,但是您的推理也不正确。

假设contestantsint的数组,初始化

 int *choice = contestants;

等于

 int *choice = &contestants[0];

换句话说,choice的值是contestants的第一个元素的地址。contestants(数组的名称(转换为&contestants[0](指针(通常称为"指针阵列"转换。

但是,由于类型是错误的,这与contestants数组的地址不同。contestants数组的地址是&contestants,它具有int (*)[4]类型(即四个int的数组的地址(。

如果您尝试初始化

 int *choice = &contestants;

结果将是汇编错误(因为int(*)[4]不能隐式转换为int *(。

您的推理

,据我所知,这是错误的。该行分配 *选择为存储为参赛者数组的值,不是吗?

有缺陷,因为contestants没有存储值。这是一组值。

确实,&contestants[0]&contestants具有相同的值,但它们的类型也不同。因此&contestant[0] == &contestants的比较不会编译。但是,如果将值转换为通用类型,例如(void *)(&contestants[0]) == (void *)(&contestants),则代码将编译,并且转换值将比较相等。

最新更新