22
回答
C语言struct的typdef问题
终于搞明白,存储TCO原来是这样算的>>>   

我不太清楚这个typedef是怎么回事, 它是在编译器搞的还是预处理期搞的, 按说应该只有#开头的语句才是预处理期搞的.

我想这样做

xxx.h

//struct tagT;有没有这句都一样

typedef struct tagT T;

xxx function(T* ,....);

xxx.c

#include "xxx.h"

struct tagT

{

    XXX

};

这样做是为了提供的接口清晰一点, 少打几个字.

我手头上有的代码就是这么搞的, 但是我这么搞编译又通不过, 实在是不知为什么.

按我的理解, 在#include "xxx.h"的时候,

//struct tagT;有没有这句都一样

typedef struct tagT T;

xxx function(T* ,....);

已经展开到xxx.c里面了, 应该一点问题没有才对. 为之奈何? @中山野鬼

 

举报
周翼翼
发帖于5年前 22回/1K+阅
共有22个答案 最后回答: 5年前

感谢大家. 问题解决了, 它又可以编译通过了.

原因很简单:

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

因为我没有定义 uchar

--- 共有 3 条评论 ---
中山野鬼回复 @周翼翼 : 喊50个美女,弹他小鸡鸡。。。 5年前 回复
周翼翼回复 @宏哥 : 50军棍~~ 5年前 回复
宏哥打50大板 5年前 回复

引用来自“中山野鬼”的答案

你对struct tagT 重定义了。
我说的是 typedef struct tagT T ; 这个。和你下面的 struct tagT { };产生了重复定义。 struct tagT; 这个只能算申明。 我查了下标准,也做了些实验。这里需要说明一下
typedef struct A B;
等于是将
struct A;
用一个typedef 映射到 B上。
这个无论你在前在后定义一次
struct A{
    int i;
};
是没有错的。但是不能重复对struct A进行定义。
你的问题,应该出现在,引用 xxx.h的其他C文件上。对这些文件的编译,如果你没有使用到
xxx func(T* ...);
的地方,没有关系。如果使用到,则对应C文件需要对T类型进行类型检查。而你的T类型,实际就是我上面的B的类型,关于 struct A 并没有出现申明。因为你藏在了 xxx.c文件里面。所以编译器会有错误。
对于其他C文件编译器需要用类型解释的地方,你还是需要公开的。除非你将对这个结构体的变量的内部操作(包含了结构体自身逻辑属性),全部封装在一个C文件里,然后你可以通过 void *的方式将地址传递过去。

编译器在语义上的处理似乎都遵循一个规则:不能在知道A的存在之前使用A,不知道是不是边展开边处理的缘故

引用来自“xyz555”的答案

struct tagT{....}这个结构声明,应该放到.h里而不能放到.c文件里。

从接口设计来说, 似乎不应该把结构体的定义暴露出去.

另外, 我最关心的是, 同样的做法, 为什么别的代码可以, 我的代码不可以.

c-algorithms 这个项目就是用这种方式的.

--- 共有 5 条评论 ---
xyz555回复 @周翼翼 : 你手里有代码是这样写的,我猜想是include这个头文件的代码里并没有使用这个struct。 5年前 回复
xyz555回复 @周翼翼 : c的struct和c++的class其实很多地方类似,那c++的class的.h是怎么定义的?类可以隐藏方法的具体实现,就是说方法具体实现可以放到.cpp里。但.h一定是定义清楚了一个类有什么属性、方法,否则编译器看到一个class a,它怎么知道这个class a里到底有什么. 5年前 回复
周翼翼回复 @xyz555 : ~~, 其实, 用户只要调函数就可以了,不能让他们直接访问结构体的东西. 从设计上来说,这样才更安全. 当然, 这个可以另外讨论, 现在我的关注点不在这里. 5年前 回复
xyz555结构应该给客户,否则客户如何访问这个结构? 5年前 回复
xyz555typedef只是定义同义词,并不是结构声明。 5年前 回复
结构体应该暴露给用户,接口里有个函数需要传结构体进去,你不知道结构体是怎样的怎么传?
--- 共有 1 条评论 ---
周翼翼有个结构体的声明就可以了吧~~. 5年前 回复

我看了一下楼主说的c-algorithms 这个项目,里面只有avl-tree.h是楼主说的这样定义,其他的struct都是在.h文件里。并且我搜索了一下其他文件除了libcalg.h这个文件里有引用外其他都没有。现在我的猜想是这样(没有用代码证实,楼主可以试试)

typedef struct _AVLTree AVLTree;

AVLTree这个结构是不允许其他文件直接使用的,只能通过调用avl-tree.c里的函数来使用。而将结构定义在.h文件里的struct是允许其他文件直接使用的。

你中了C++的毒,解药如下:

给它取一个漂亮的名字(naming),把它放在合适的盒子里面(.h)

怎么简单怎么用,至于"隐藏"数据类型定义,其实是面相对象遗毒. 一个好名字,一个好位置就解决了.

至于private, 只要你有指针,user space就没有private,你懂的.

********************************************

楼上有些同学说对了,typedef 只是alias.

顶部