简体   繁体   English

C:Typedef结构和指针异常

[英]C: Typedef structure and pointers anomaly

I was on my Data Structures classes and this confused me. 我在数据结构课程上,这让我感到困惑。

It's related with pointers properties i guess, but on my research I didn't find any real explanation, any idea why C allows this? 我猜它与指针属性有关,但是在我的研究中,我没有找到任何真正的解释,不知道为什么C允许这样做?

Run-able code: http://ideone.com/kgh3LF 可运行的代码: 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;
}

You incorrectly assumed that your second structure "calls" the first one. 您错误地假定您的第二个结构“调用”第一个结构。 It doesn't. 没有。

In reality the first struct declaration declares as untagged struct type with typedef alias struct_one . 实际上,第一个struct声明使用typedef别名struct_one声明为未标记的 struct type。 The only way to refer to this type is struct_one . 引用此类型的唯一方法是struct_one Just struct_one , not struct struct_one . 只是struct_one ,而不是struct struct_one

The second struct declaration declares struct struct_two , which refers to a type struct struct_one . 第二个struct声明声明struct struct_two ,它引用类型struct struct_one This latter type has absolutely nothing to do with the previously declared type struct_one : struct struct_one and struct_one are two completely different, unrelated types. 后一种类型与先前声明的struct_one类型完全无关: struct struct_onestruct_one是两个完全不同的,不相关的类型。 Your reference to struct struct_one inside the second struct is seen as an introduction , a declaration of a completely new type struct struct_one . 您在第二个struct中对struct struct_one引用被视为介绍 ,这是一个全新的struct struct_one类型的声明 The compiler assumes that you will define that type later (if necessary). 编译器假定您稍后将定义该类型(如有必要)。

Since you are not doing anything else in your code, you do not run into any problems caused by such mistake. 由于您没有在代码中执行任何其他操作,因此不会遇到由此类错误引起的任何问题。 As an additional illustration of what could happen, see the following example 作为可能发生的情况的其他说明,请参见以下示例

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

This code will immediately produce a diagnostic message from the compiler, because s2.ptr = p; 该代码将立即从编译器产生诊断消息,因为s2.ptr = p; assignment is illegal: the pointer types are unrelated. 分配是非法的:指针类型无关。 The pointer of the left hand side is struct struct_one * and the pointer on the right-hand side is just struct_one * . 左侧的指针是struct struct_one * ,而右侧的指针只是struct_one *

Once again, in C language when you use struct <something> syntax in contexts that do not require a complete type, you can write virtually anything in place of <something> : a complete gibberish (as long as it is a lexically valid identifier). 再一次,在C语言中,当您在不需要完整类型的上下文中使用struct <something>语法时,几乎可以代替<something>编写任何<something> :完全乱码(只要它是词法上有效的标识符) 。 If the type is not yet known, the compiler will simply assume that you are introducing a new type, eg 如果类型未知,编译器将简单地假设您正在引入一个新类型,例如

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

The above is a perfectly valid C program. 上面是一个完全有效的C程序。

This is allowed because sometimes you have two struct types that each contain a pointer to the other. 这是允许的,因为有时您有两个结构类型,每个结构类型都包含指向另一个的指针。 You need to be able to declare a pointer to the second type in the first one, even though the second struct hasn't been declared yet. 您需要能够在第一个类型中声明一个指向第二种类型的指针,即使尚未声明第二个结构。 If you couldn't forward reference a struct pointer type, you'd have the paradox that each one has to be declared before the other. 如果您不能转发引用结构指针类型,则有一个矛盾,那就是每个人都必须在另一个人之前被声明。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM