这个问题似乎是一个经典问题,但我找不到答案:
我有两个用C语言编写的结构类型------结构类型A和结构类型B,B使用A而A同时使用B.
在a.h中:
#include "b.h"
struct B;
typedef struct A {
void (*func)(struct B* b);
}A;
在b.h中:
#include "a.h"
typedef struct B {
A a;
}B;
虽然这会起作用,但它有一个结果---当使用函数fun“func”时,如果我传递一个在表单中声明的变量:
B* someb;
不
struct B* someb;
编译时会出现警告,说不兼容的指针类型。这是正常的吗?我可以避免这个警告吗?
答案 0 :(得分:2)
在a.h
标题文件中,只需删除第#include "b.h"
行即可。您只需要前瞻性声明struct B;
。
该更改将修复循环包含依赖项,并使使用这些标题的任何代码更加清晰。
然后,只要您想要使用B
结构,只需添加b.h
,并使用或不使用struct
关键字。
一些代码用于说明:a.h
头文件:
/* a.h */
struct B;
typedef struct A {
void (*func)(struct B* b);
} A;
b.h
头文件:
/* b.h */
#include "a.h"
typedef struct B {
A a;
} B;
使用这些头文件的文件:
/* some_file.c */
#include "b.h"
void fun() {
B someb;
someb.a.func(&someb);
}
void fun2() {
struct B someb;
someb.a.func(&someb);
}
fun
和fun2
都很好(从编译器的角度来看 - func
尚未初始化,因此调用它会在运行时导致问题。)< / p>
答案 1 :(得分:2)
循环包含依赖项永远不是一个好主意。
最简单的方法是在“a.h”中为struct
标记和 typedef
提供前向声明
typedef struct A A;
typedef struct B B;
答案 2 :(得分:0)
函数func
,因为你声明它获取了一个指向struct B
对象的指针,所以在调用函数时你应该这样做:
B* somePointer; //because of your typedef you can omit struct
func(somePointer);
我省略了你应该管理的内存分配部分......
正如问题Compiler Warning: Initialization incompatible pointer type所示,您应该传递一个指向该函数的指针,以便在对象中显示更改,否则您只是传递一个struct B的副本,并且您所做的每个更改都将仅在功能范围。
我认为这是警告的原因。
答案 3 :(得分:0)
struct whatever { /* ... */ };
定义了一种新类型
新类型名称为 struct whatever
。
您可以在定义类型的同一语句中使用typedef
为类型定义另一个名称
typedef struct whatever { /* ... */ } newtypename;
或以不同的陈述
struct whatever { /* ... */ };
typedef struct whatever newtypename;
您甚至可以定义没有名称的struct
类型并为其获取新名称
typedef struct { /* ... */ } newtypenameforstructwithnotag;