Bla*_*iev 15 c pointers typedef
可能重复:
Typedef指针是个好主意?
我在许多使用过的API中都看到了这种奇怪之处:
typedef type_t *TYPE;
Run Code Online (Sandbox Code Playgroud)
我的观点是声明一个类型的变量TYPE将不会清楚地表明事实上已经声明了一个指针.
你和我一样认为这会带来很多困惑吗?这是否意味着强制执行封装,还是有其他原因?你认为这是一种不好的做法吗?
Joh*_*all 24
一般来说,这是一种不好的做法.重要的问题是它不能很好地与const:
typedef type_t *TYPE;
extern void set_type(TYPE t);
void foo(const TYPE mytype) {
set_type(mytype); // Error expected, but in fact compiles
}
Run Code Online (Sandbox Code Playgroud)
为了使作者foo()能够表达他们真正的意思,提供的图书馆还TYPE必须提供CONST_TYPE:
typedef const type_t *CONST_TYPE;
Run Code Online (Sandbox Code Playgroud)
所以foo()可以有签名void foo(CONST_TYPE mytype),此时我们已经陷入了闹剧.
因此经验法则:
创建结构的typedef(特别是不完整的结构),而不是指向那些结构的指针.
如果底层结构的定义不是公开可用的(这通常是值得称赞的),那么该封装应该由结构提供不完整,而不是由不方便的typedef提供:
struct type_t;
typedef struct type_t type_t;
void set_type(type_t *);
int get_type_field(const type_t *);
Run Code Online (Sandbox Code Playgroud)
一个常见的习语是用类型后缀_p来表示它是一个指针,同时仍保留指针质量.
有时,如果指向的结构不可公开,则只需使用指针类型.这有助于促进数据隐藏.即
typedef struct hidden_secret_object * object;
void change_object(object foo);
Run Code Online (Sandbox Code Playgroud)
这允许您在hidden_secret_object不破坏外部代码的情况下更改结构化方式.
我也不清楚.我也不喜欢完全大写的类型(我试着为#defines保留那些).
这种方式通过认为它实际上是一种值类型而很容易自欺欺人,而我们正在讨论指针类型.可以使用智能指针完全抽象出指针类型,但这在C语言中并不常见.
后缀(如前所述)_p,_ptr,Pointer或沿着这些线的任何东西都会产生清晰度; 增加打字,这是真的,但会阻止你犯愚蠢的错误(例如使用'.'而不是' - >',......)会花费你宝贵的开发时间.
这取决于你想要达到的目标.对于您提出的问题,您的问题没有任何有意义的"是或否"答案.
你说有时它"不清楚是否声明了指针".但在这种使用模式下,这正是重点!它应该是"不清楚".事实上,该类型恰好是一个混淆的指针,这不关你的事.这是你不需要知道而不应该依赖的东西.
此使用模型的典型示例是va_list标准库中的类型.在某些实现中,它可能很容易成为指针类型的typedef.但那是你不应该知道或依赖的东西.
另一个例子是HWNDWindows API中的类型定义.它也是指针类型的typedef,但这不关你的事.
*每次都输入字符.在这种情况下,typedef(并且将始终是)代表指针类型的事实向用户公开.通常这种用法不是一种好的编程习惯.如果用户想要创建别名以避免*每次都键入,他们可以自己完成.由于您在OP中已经提到过的原因,此使用模型通常会导致代码更加模糊.
在Windows API中也可以找到这种错误使用typedef的示例.Typedef名称PINT完全遵循有缺陷的使用模型.