指针 - 函数定义中结构后的“*”是什么意思?
Pointers - What does a '*' after a struct mean in the function definition?
我正在学习 C 中的指针。我遇到了一个我不理解 return 类型的函数。函数定义为:
extern PHONE* findPhone()
PHONE 是一个结构。函数 return 是一个 PHONE 指针。如果它想这样做,函数定义中的 return 类型不应该是 '*PHONE'
此位置的星号是 声明符 语法的一部分。它表示一个指针。
在 C 语言中,声明 是一个 declaration-specifiers 列表,后跟一个 声明符列表 带有可选的初始化。
declaration-specifiers 指定类型,如 int
、double
、long long
、struct foo
或类型定义名称。 (它们还包括其他类型的说明符,如 extern
和 inline
,这些说明符在此答案中无关紧要。)无论类型如何 <i>T</i>
这是,声明符然后指定具有 <i>T</i>
.
类型的事物
声明符有几种形式:
- 一个普通的名字,
<i>D</i>
,表示<i>D</i>
的类型为 <i>T</i>
.
- 圆括号中的声明符,
(<i>D</i>)
,表示表达式(<i>D</i>)
的类型为 <i>T</i>
,表示 <i>D</i>
也有类型 <i>T</i>
,因此这与声明符中的普通名称具有相同的含义。但是,它将声明符分组以进行进一步解析。
- 带括号的声明符,
<i>D</i>[<em>expression</em>]
,表示表达式<i>D</i>[i]
将具有类型 <i>T</i>
,这意味着<i>D</i>
必须是类型数组。
- 带有星号的声明符,
*<i>D</i>
,表示表达式 *<i>D</i>
将具有类型 <i>T</i>
,因此 <i>D</i>
必须是指向 <i>T</i>
. 的指针
- 带括号的声明符,
<i>D</i>()
,表示表达式<i>D</i>()
将具有类型 <i>T</i>
,这意味着 <i>D</i>
必须是 returns <i>T</i>
. 的函数
这些表格可以组合。声明符 (*<i>D</i>)[]
表示 (*<i>D</i>)[]
具有类型 <i>T</i>
,因此 (*<i>D</i>)
是<i>T</i>
的数组,所以*<i>D</i>
也是<i>T</i>
的数组,所以<i>D</i>
是指向 <i>T</i>
.
数组的指针
从本质上讲,声明符是一个名称将如何在表达式中使用的图片,名称的实际类型是通过从该表达式的类型向后计算得出的。
所以extern PHONE* findPhone()
在语法上是extern PHONE
和* findPhone()
。它说 * findPhone()
的类型是 PHONE
。所以 findPhone()
是一个指向 PHONE
的指针。所以 findPhone
是一个返回指向类型 PHONE
.
的指针的函数
(上面没有讨论声明符的其他部分,例如函数的参数列表和声明数组时括号内容的一些选项。)
extern PHONE* findPhone()
被解析为
extern PHONE (*findPhone())
C 中的声明分为两个主要部分 - 随后是一系列 声明说明符 (类型说明符、存储 class 说明符、类型限定符等)通过 comma-separated 个 声明符列表 .
Array-ness、function-ness 和 pointer-ness 被指定为声明符的一部分。在上面的声明中,extern PHONE
是声明说明符,*findPhone()
是声明符;它表示 findPhone()
函数 returns 指向 PHONE
.
的指针
想法是声明符的结构与同一类型代码中表达式的结构相匹配。在这种情况下,如果您想访问函数 returns 的 PHONE
对象,您将调用该函数并取消引用结果:
a_phone = *findPhone();
表达式*findPhone()
的类型是PHONE
,因此函数的声明是
PHONE *findPhone();
除了分隔相同类型的标记(例如 extern
和 PHONE
,它们都是标识符)之外,空格并不重要。因为 *
字符永远不能成为标识符的一部分,所以写
也没关系
extern PHONE* findPhone();
或
extern PHONE *findPhone();
或
extern PHONE * findPhone() ;
甚至
extern PHONE*findPhone();
它们都将以相同的方式解释。
我正在学习 C 中的指针。我遇到了一个我不理解 return 类型的函数。函数定义为:
extern PHONE* findPhone()
PHONE 是一个结构。函数 return 是一个 PHONE 指针。如果它想这样做,函数定义中的 return 类型不应该是 '*PHONE'
此位置的星号是 声明符 语法的一部分。它表示一个指针。
在 C 语言中,声明 是一个 declaration-specifiers 列表,后跟一个 声明符列表 带有可选的初始化。
declaration-specifiers 指定类型,如 int
、double
、long long
、struct foo
或类型定义名称。 (它们还包括其他类型的说明符,如 extern
和 inline
,这些说明符在此答案中无关紧要。)无论类型如何 <i>T</i>
这是,声明符然后指定具有 <i>T</i>
.
声明符有几种形式:
- 一个普通的名字,
<i>D</i>
,表示<i>D</i>
的类型为<i>T</i>
. - 圆括号中的声明符,
(<i>D</i>)
,表示表达式(<i>D</i>)
的类型为<i>T</i>
,表示<i>D</i>
也有类型<i>T</i>
,因此这与声明符中的普通名称具有相同的含义。但是,它将声明符分组以进行进一步解析。 - 带括号的声明符,
<i>D</i>[<em>expression</em>]
,表示表达式<i>D</i>[i]
将具有类型<i>T</i>
,这意味着<i>D</i>
必须是类型数组。 - 带有星号的声明符,
*<i>D</i>
,表示表达式*<i>D</i>
将具有类型<i>T</i>
,因此<i>D</i>
必须是指向<i>T</i>
. 的指针
- 带括号的声明符,
<i>D</i>()
,表示表达式<i>D</i>()
将具有类型<i>T</i>
,这意味着<i>D</i>
必须是 returns<i>T</i>
. 的函数
这些表格可以组合。声明符 (*<i>D</i>)[]
表示 (*<i>D</i>)[]
具有类型 <i>T</i>
,因此 (*<i>D</i>)
是<i>T</i>
的数组,所以*<i>D</i>
也是<i>T</i>
的数组,所以<i>D</i>
是指向 <i>T</i>
.
从本质上讲,声明符是一个名称将如何在表达式中使用的图片,名称的实际类型是通过从该表达式的类型向后计算得出的。
所以extern PHONE* findPhone()
在语法上是extern PHONE
和* findPhone()
。它说 * findPhone()
的类型是 PHONE
。所以 findPhone()
是一个指向 PHONE
的指针。所以 findPhone
是一个返回指向类型 PHONE
.
(上面没有讨论声明符的其他部分,例如函数的参数列表和声明数组时括号内容的一些选项。)
extern PHONE* findPhone()
被解析为
extern PHONE (*findPhone())
C 中的声明分为两个主要部分 - 随后是一系列 声明说明符 (类型说明符、存储 class 说明符、类型限定符等)通过 comma-separated 个 声明符列表 .
Array-ness、function-ness 和 pointer-ness 被指定为声明符的一部分。在上面的声明中,extern PHONE
是声明说明符,*findPhone()
是声明符;它表示 findPhone()
函数 returns 指向 PHONE
.
想法是声明符的结构与同一类型代码中表达式的结构相匹配。在这种情况下,如果您想访问函数 returns 的 PHONE
对象,您将调用该函数并取消引用结果:
a_phone = *findPhone();
表达式*findPhone()
的类型是PHONE
,因此函数的声明是
PHONE *findPhone();
除了分隔相同类型的标记(例如 extern
和 PHONE
,它们都是标识符)之外,空格并不重要。因为 *
字符永远不能成为标识符的一部分,所以写
extern PHONE* findPhone();
或
extern PHONE *findPhone();
或
extern PHONE * findPhone() ;
甚至
extern PHONE*findPhone();
它们都将以相同的方式解释。