【问题标题】:Simple linked list in C WindowsC Windows中的简单链表
【发布时间】:2012-09-26 18:26:48
【问题描述】:

我用 C 编码已经很久了,现在我什至无法创建链表:(NodeType 结构可能有什么问题? 我什至尝试了this 示例,但仍然出现类似的错误。

我需要创建可以在 linux 和 windows 上运行的链表(无需大量修改)。

我使用:cl myFile.c 命令编译。

错误信息:

Microsoft (R) 32 位 C/C++ 优化编译器版本 16.00.40219.01 对于 80x86 版权所有 (C) Microsoft Corporation。保留所有权利。

unlock.c unlock.c(46) : error C2275: 'Node' : 非法使用这种类型 作为表达 unlock.c(17):参见“节点”的声明 unlock.c(46):错误 C2146:语法错误:缺少“;”在标识符 'a' unlock.c(46) 之前: 错误 C2065:“a”:未声明的标识符

源代码:

#include <stdio.h>
#include <windows.h>
#include<stdlib.h>


typedef enum {STABLE, RPUSH, LPUSH} STATUS_TYPE;


typedef struct NodeType
{
    struct NodeType* _left;
    struct NodeType* _right;
    int _value;
}Node;

typedef struct AnchorType
{
    struct Node* _mostLeft;
    struct Node* _mostRight;
    STATUS_TYPE _status;
} Anchor;

Node CreateNode(int data)
{
    Node newNode;
    newNode._value = data;
    newNode._left = NULL;
    newNode._right = NULL;

    return newNode;
}


int main()
{
    Anchor anchor;
    anchor._mostLeft = NULL;
    anchor._mostRight = NULL;
    anchor._status = STABLE;


    Node a; //<-- What might be wrong ?

    return 0;
}

感谢您的帮助。

【问题讨论】:

  • 请注意,struct AnchorType 定义中的 _mostLeftmostRight 成员应仅声明为 Node*struct NodeType *
  • 可能来自windows.h 的一些垃圾会搞砸事情。如果删除该包含,它会编译吗? (它应该是,因为它是合法的 C,尽管 pb2q 指出了你犯的一个错误。)
  • @DanielFischer:C99 是合法的,但他的编译器不支持 C99。该程序不是合法的 C89/C90。
  • @BenVoigt 啊,总是忘记微软编译器是 C89。

标签: c windows visual-studio linked-list


【解决方案1】:

微软专注于 C++ 编译器,他们的 C 支持已经过时了几十年。

Microsoft 编译器不支持的较新 C 标准的功能之一是能够在函数中间声明变量。

将声明移到顶部,一切都会好的:

int main()
{
    Anchor anchor;
    Node a; // ok here
    anchor._mostLeft = NULL;
    anchor._mostRight = NULL;
    anchor._status = STABLE;


    //Node a; but not here

    return 0;
}

【讨论】:

  • 我怎么能忘记 C 中的变量声明...谢谢。
  • 这不是一个真正的缺陷;任何可移植的 c 程序都应该在分配之前声明,这只是常识,并且更容易推理本地堆栈组织。此外,它们确实支持使用匿名作用域在作用域中间声明; { declare; assign; use; }
  • @Dmitry:不管您的偏好如何,C++ 和 C 标准委员会都认为允许将变量声明与语句混合使用非常重要,足以使其合法化。深度嵌套的语句块会损害可读性,因此在需要引入新变量时添加它们并不理想。
  • @ben 这是偏好;我发现添加匿名范围以增加可读性,因为您明确限制了变量的生命周期,从而让读者知道变量何时不再与范围相关。在许多范围内,中途定义的变量会立即被使用,并且不会被引用超过 300 行;当变量不再相关时,一个小的匿名范围会让读者知道。尤其是在调用需要 out 变量的 windows api 函数时,您会为其创建一个虚拟变量,之后再也不使用它。
  • @Dmitry:是的,我保留为短期变量保存嵌套范围,这意味着不会将它们用于中间函数引入的每个变量。
【解决方案2】:

问题是structure 标记为NodeType,但typedef 标记为Node。两者应该指的是同一件事。如:

typedef struct Node
{ 
    struct Node* _left; 
    struct Node* _right; 
    int _value; 
} Node;

这会创建一个名为 Nodetypedef,即 struct Node

在 Microsoft 编译器目标代码中,您通常会看到:

typedef struct Node
{ 
    struct Node* _left; 
    struct Node* _right; 
    int _value; 
} tagNode;

typedef struct Anchor
{ 
    struct Node* _mostLeft; 
    struct Node* _mostRight; 
    STATUS_TYPE _status; 
} tagAnchor; 

tagNode 永远不会在 Microsoft 编译器代码中使用,只会在 Node 中使用。 Microsoft 编译器会对此非常满意,阅读您的代码的人会知道您指的是结构。

如需更多详细信息,包括 C 和 C++ 命名类型定义和标签的历史,请参阅发布在以下位置的 anwser:Difference between 'struct' and 'typedef struct' in C++?

【讨论】:

    猜你喜欢
    • 2014-04-04
    • 1970-01-01
    • 2010-11-08
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 2011-09-17
    相关资源
    最近更新 更多