英文:
warning: assignment to ‘struct node_t *’ from incompatible pointer type ‘node_t *
问题
我正在处理一个链表,并尝试将链表中节点(node_t)的信息分配给一个单独的结构体(list_stats_t)。
```c
struct node
{
char firstName[50], lastName[50], major[50], classStanding[50];
bday bd; // 这个结构体只包含日、月和年的整数值
struct node* next;
};
typedef struct node node_t;
struct stats
{
// 指向链表中年龄最大和最小的人的节点指针
struct node_t* oldest;
struct node_t* youngest;
// 存储每个月份的生日数量(0 = 一月,11 = 十二月)
int numBD[12];
};
typedef struct stats list_stats_t;
list_stats_t getListStats(node_t *head)
{
node_t* temp = head;
// 创建要返回的对象并将其初始化为链表中的第一个节点
list_stats_t stat;
node_t* oldest = temp;
node_t* youngest = temp;
while (temp != NULL) // 遍历链表以查找年龄最大和最小的人
{
// 如果当前节点不是最老的,则将最老的设为下一个节点
if (isOlder(oldest) == false)
{ oldest = temp->next; }
if (isOlder(youngest) == false)
{ youngest = temp->next; }
temp = temp->next; // 下一个值
}
// 编译器警告
stat.oldest = oldest;
stat.youngest = youngest;
return stat;
}
我期望在结构体 stats 中的 node_t 值被分配给 getListStats() 函数中的 node_t 值。没有编译错误,只有警告,但我更喜欢避免这些警告。
<details>
<summary>英文:</summary>
I'm working with a linked list and trying to assign information from nodes in a list (node_t) to a separate struct (list_stats_t)
struct node
{
char firstName[50], lastName[50], major[50], classStanding[50];
bday bd; // this struct just contains int values of day, month, and year
struct node* next;
};
typedef struct node node_t;
struct stats
{
// node pointer pointing at the oldest and youngest person in the list
struct node_t* oldest;
struct node_t* youngest;
// holding the number of birthdays in each month (0 = Jan. & 11 = Dec.)
int numBD[12];
}; typedef struct stats list_stats_t;
list_stats_t getListStats(node_t head)
{
node_t temp = head;
// creates object to be returned and initializes it to the first node in a list
list_stats_t stat;
node_t* oldest = temp;
node_t* youngest = temp;
while (temp != NULL) // loops through the list to find the oldest and youngest person
{
// if current node isn't the oldest, set the oldest to the next node
if (isOlder(oldest) == false)
{ oldest = temp->next; }
if (isOlder(youngest) == false)
{ youngest = temp->next; }
temp = temp->next; // next value
}
// compiler warnings
stat.oldest = oldest;
stat.youngest = youngest;
return stat;
}
I was expecting the node_t values in struct stats to be assigned to the node_t values within getListStats(). There aren't any compiler errors, just warnings but I prefer to avoid those as well
</details>
# 答案1
**得分**: 3
你有两个关于节点类型的名称:
* `struct node`
* `node_t`
`struct node_t` 与这些不同,并不是你打算使用的类型。
<details>
<summary>英文:</summary>
You have two names for your node type:
* `struct node`
* `node_t`
`struct node_t` is different than these, and not the type you intended to use.
</details>
# 答案2
**得分**: 1
编译器消息的来源是`node_t`与`struct node_t`之间的差异,其中`node_t`是一个`typedef`,而不是一个结构标签。
为了解释为什么会出现像"warning: assignment to ‘struct node_t *’ from incompatible pointer type ‘node_t *"这样奇怪的内容:
C语言有不完整类型(incomplete type)的概念,这意味着它允许您在稍后声明类型时使用占位符。一个示例是在`struct node { ... };`声明中的`struct node* next;`。编译器实际上在达到`struct node* next;`时不知道`struct node`是什么 - 这只是一个占位符。一旦编译器在结构声明之后达到最终的`;`,它就知道从那时起`struct node`是什么。
不完整类型/前向声明在各种类似的情况下很有用。虽然我们在编译器知道对象声明之前不能声明不完整类型的对象 - 我们只能声明指向它的指针。
因此,类似`int main (void) { struct bananas* p; }`的东西是有效的C程序,即使没有任何地方存在这样的结构声明 - `p`是指向不完整类型的指针。因此,在编译器发现完整类型之前,我们不能真正使用`p`。
因此,在您的情况中,拼写错误`struct node_t*`创建了一个指向不完整类型的指针,与此时的`struct node`/`node_t`不同,它是一个完整类型。它们是不兼容的类型,因此出现了编译器消息。严格来说,这使得您的程序不符合C语言标准,但编译器选择创建一个非标准的可执行文件。只要给程序员一个有关已发现问题的消息,它可以这样做(如果您想要在类似GCC的编译器中防止这种情况,可以使用`-pedantic-errors`编译)。
<details>
<summary>英文:</summary>
The source of the compiler message is `node_t` vs `struct node_t` where `node_t` is a `typedef`, not a struct tag.
To explain _why_ it would spit out something as strange as "warning: assignment to ‘struct node_t *’ from incompatible pointer type ‘node_t *":
C has the concept of _incomplete type_, meaning it allows you to use placeholders for a type to be declared later. An example of this is `struct node* next;` inside your `struct node { ... };` declaration. The compiler doesn't actually know what a `struct node` is by the time it reaches `struct node* next;` - this is just a placeholder. Once the compiler reaches the final `;` after the struct declaration, then it knows what a `struct node` is from there on.
Incomplete type/forward declaration is useful in various similar situations. Although we cannot declare an object of an incomplete type until the compiler knows the object declaration - we can only declare a pointer to one.
Therefore something like `int main (void) { struct bananas* p; }` is a valid C program, even though there's no such struct declaration present anywhere - `p` is a pointer to an incomplete type. And as such we cannot really use `p` until a complete type has been spotted by the compiler.
So in your case the typo `struct node_t*` created a pointer to an incomplete type, different from `struct node`/`node_t` which at that point is a complete type. They are not compatible types, hence the compiler message. Strictly speaking this made your program invalid C, but the compiler chose to create a non-standard executable anyway. Which it may do as long as it gave the programmer a message about spotted problems. (If you want to prevent that with gcc-like compilers, then compile as `-pedantic-errors`.)
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论