【问题标题】:C: Typedef structure and pointers anomalyC:Typedef结构和指针异常
【发布时间】:2015-08-25 02:37:04
【问题描述】:

我在学习数据结构课程,这让我很困惑。

我猜它与指针属性有关,但在我的研究中我没有找到任何真正的解释,知道为什么 C 允许这样做吗?

可运行代码:http://ideone.com/kgh3LF

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

/* Declaring a typedef struct  */
typedef struct{
    int a;
    char b[10];
}struct_one;

/* Declaring another structure, with an intentional wrong calling of the first structure */
struct struct_two{
    int p;
    char q[10];

    /* This doesn't work as expected... should be: struct_one var; */
    // struct struct_one var;

    /* THIS ONE DOES WORK!!, and i'm not sure why */
    struct struct_one *ptr;
};

int main(void) {
    /* code */
    return 0;
}

【问题讨论】:

  • 在声明指向相同的指针时,您正在隐式前向声明 struct struct_one 类型。如果您想看到它吹出大块,请尝试在main() 中尝试struct two obj; obj.ptr = malloc(sizeof *obj.ptr);,从而将significant doubt 借给“这个确实有效!”
  • 这就是为什么我不同意'common'(?)智慧不 typedef 你的结构。 typedef 名称中的拼写错误会被编译器捕获,但结构标记中的拼写错误可能不会,这取决于它的使用方式。

标签: c pointers data-structures typedef


【解决方案1】:

您错误地假设您的第二个结构“调用”了第一个结构。没有。

实际上,第一个结构声明声明为 untagged 结构类型,typedef 别名为 struct_one。引用此类型的唯一方法是struct_one。只是struct_one,而不是struct struct_one

第二个结构声明声明了struct struct_two,它引用了一个类型struct struct_one。后一种类型与之前声明的类型struct_one 完全无关:struct struct_onestruct_one 是两种完全不同的、不相关的类型。您在第二个结构中对struct struct_one 的引用被视为一个介绍,一个全新类型struct struct_one声明。编译器假定您稍后会定义该类型(如果需要)。

由于您没有在代码中执行任何其他操作,因此您不会遇到由此类错误引起的任何问题。作为可能发生的情况的补充说明,请参见以下示例

int main(void) {
    struct_one *p = 0;
    struct struct_two s2;
    s2.ptr = p;       
    return 0;
}

此代码将立即从编译器生成诊断消息,因为s2.ptr = p; 赋值是非法的:指针类型不相关。左边的指针是struct struct_one *,右边的指针就是struct_one *

再一次,在 C 语言中,当您在不需要完整类型的上下文中使用 struct &lt;something&gt; 语法时,您几乎可以写任何东西来代替 &lt;something&gt;:完全是胡言乱语(只要它在词法上有效)标识符)。如果类型未知,编译器将简单地假设您正在引入一个新类型,例如

int main() {
  struct klshcjkzdcdsamcbsj78q43698 *p = 0;
}

以上是一个完全有效的 C 程序。

【讨论】:

    【解决方案2】:

    这是允许的,因为有时你有两个结构类型,每个都包含一个指向另一个的指针。您需要能够在第一个类型中声明指向第二种类型的指针,即使尚未声明第二个结构。如果你不能前向引用一个结构指针类型,你就会遇到一个悖论,那就是必须先声明每个指针类型。

    struct first {
        int a;
        struct second *second_ptr; // This is allowed
    };
    struct second {
        int b;
        struct first *first_ptr;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-03
      • 1970-01-01
      • 2013-12-19
      • 2020-04-15
      • 1970-01-01
      • 2015-07-10
      • 2013-02-15
      • 2023-04-04
      • 2016-07-05
      相关资源
      最近更新 更多