这是我的代码:
#include <stdio.h>
struct entry
{
int value;
struct entry *next;
};
struct entry * findEntry (struct entry *listPtr, int match)
{
while (listPtr != (struct entry *) 0)
if (listPtr->value == match)
return (listPtr);
else
listPtr = listPtr->next;
return (struct entry *) 0;
}
int main(void)
{
struct entry * findEntry(struct entry * listPtr, int match);
struct entry n1, n2, n3;
struct entry * listPtr, *listStart = &n1;
int search;
n1.value = 100;
n1.next = &n2;
n2.value = 200;
n2.next = &n3;
n3.value = 100;
n3.next = 0;
printf("Enter value to locate: ");
scanf ("%i", &search);
listPtr = findEntry (listStart, search);
if (listPtr != (struct entry *) 0)
printf( "Found %i.\n", listPtr->value);
else
printf("Not found.\n");
return 0;
}
所以对于这一行:
struct entry *findEntry (struct entry *listPtr, int match)
为什么在查找条目前面有*
?因为它应该是一个函数声明,但*findEntry
是一个指针?我根本不明白这句话是什么......
在书中解释是:指定函数findEntry()
返回一个指向条目结构的指针,并且它将这样的指针作为其第一个参数,将整数作为其第二个
在这种情况下需要*
符号吗?
谢谢
答案 0 :(得分:1)
想象一下有人告诉你,23+45
等于275
,然后通过以下逻辑对其进行解释:我们必须单独计算3+4
并保持2
和{{两边都没有变化。当然,这没有任何意义。 5
符号的正确含义并不意味着应该将23+45
片段从其中撕掉并单独处理。
当你将3+4
与声明的其余部分隔离开来并得出结论它声明*findEntry
作为指针时,你实际上会犯同样的错误。您的声明中没有findEntry
这样的实体。声明语法规定右侧的*findEntry
位首先绑定到名称(...)
。然后我们才开始考虑名称左侧的findEntry
。
这意味着您的*
声明以findEntry
绑定开头,表示findEntry(...)
是一个函数。只有在此之后我们才会考虑findEntry
位,获取*
,它告诉我们*findEntry(...)
是一个返回指针的函数。
答案 1 :(得分:0)
C的语法没有为返回值提供参数名称(因为它无论如何都不能在代码中使用)。宣言:
struct entry * findEntry (struct entry *listPtr, int match)
可写:
struct entry *
findEntry (struct entry *listPtr, int match)
(实际上是在某些编码标准中以这种方式编写的)。
并且声明了一个名为findEntry
的函数,它返回指向struct entry
(a struct entry *
)的指针。如果没有*
,该函数将返回struct entry
。
答案 2 :(得分:0)
为什么在查找条目前面有*?因为它应该是一个函数声明,但
*findEntry
是一个指针?我根本不明白这句话是什么......
是的,它表明findEntry
是一个返回指针值的函数。
C声明语法以表达式的类型为中心。例如,假设我们有一个指向int
的指针,我们想要访问指向int
的值。我们在指针上使用一元*
运算符,如下所示:
x = *p;
表达式 *p
的类型为int
,因此当我们声明指针变量p
时,我们会这样做
int *p;
声明符 *p
指定p
的“指针”。类似地,假设我们有一个函数返回指向int
的指针,并且我们想再次访问指向的整数值。同样,我们对函数返回的值使用一元*
运算符:
x = *f();
表达式 *f()
的类型为int
,所以当我们声明函数时,我们会写
int *f(void); // void means f takes no arguments
在这种情况下,f
的“function-ness”和“pointer-ness”都由声明者*f(void)
给出。
现在,我们可以决定将f
的返回值分配给p
:
p = f();
请注意,在这种情况下,我们不在任一表达式上使用*
运算符,因为这次我们对指针值感兴趣,不是指向的整数值。但是我们仍然需要在声明中使用*
来表示它们处理指针值。
在表达式和声明语法中,后缀()
和[]
运算符之前绑定(优先级高于)一元*
运算符。因此:
T *f(); // declares f as a function returning a pointer to T
T (*f)(); // declares f as a pointer to a function returning T
T *a[N]; // declares a as an N-element array of pointer to T
T (*a)[N]; // declares a as a pointer to an N-element array of T
因此,当您发现一个有点复杂的声明时,从最左边的标识符开始,使用上面的优先规则。递归地将这些规则应用于任何函数参数。所以,鉴于你的声明
struct entry * findEntry (struct entry *listPtr, int match);
我们将其视为
findEntry -- findEntry
findEntry ( ) -- is a function taking
findEntry ( listPtr ) -- parameter listPtr
findEntry ( *listPtr ) -- is a pointer to
findEntry (struct entry *listPtr ) -- struct entry
findEntry (struct entry *listPtr, match) -- parameter match
findEntry (struct entry *listPtr, int match) -- is an int
* findEntry (struct entry *listPtr, int match) -- returning a pointer to
struct entry * findEntry (struct entry *listPtr, int match); -- struct entry