如何降低程序可读性(三)

要命的typedef, 之前总觉的typedef和#define很相似,但是肯定是有差异的对吧,先举个例子看看他们的差别。

#define Int_t int
unsigned Int_t i;
typedef int Int_w;
unsigned  Int_w i;

首先看unsigned Int_t i;这个肯定是正确的,因为就等同于unsigned int i;而后者 unsigned Int_w i;会报错,因为typedef会保证定义的类型声明的变量类一致,这明显与unsigned 这个前缀相冲突。只要将unsigned 去掉就可以通过编译。

#define int_t int *
typedef int * int_w;
int_t a, b;
int_w c, d;

分解int_t a,b; 可以得到 int * a,b; 然而分解int_w c,d; 可以得到 int * c;int *d;

以上的例子可以很明显看到typedef和define的区别;

然后来看下一个例子

void(*signal(int sig, void(*func)(int)))(int);

怎么用typedef将该函数进行分解呢?

先将void(*func)(int)单独拿出来。

首先看func是什么?一个指针,指向什么?指向一个返回值是void并且还有一个int参数的函数。

接下来不妨将typedef  void(*func)(int);

 然后将

void(*signal(int sig, void(*func)(int)))(int);

进行替换操作

第一步结果如下 void(*signal(int sig,func))(int);

第二步结果如下 func signal(int,func);

不要想到多,func这里只是一个小指针。


走到这步怎么再让你的程序再难度一点呢?对糟糕的命名方式。

如下个例子

struct foo{ int foo; }foo;

标签,成员名,对象名,嗯很好这样就肆无忌惮的通过编译器的安检。

那就再恶心一点吧。

typedef struct baz{ int baz; } baz;
        struct baz a;//使用结构体标签
	       baz b;//使用结构体类型
没错,编译器安检照样过。

为了区分以上两位大佬我们可以将名称稍微做一下变化,变化如下

  typedef struct baz{ int baz_t; }baz_w;

那么baz_w a;照样能通过安检,因为typedef引入baz_w时同样引入了baz结构体标签;

若是将改成

struct baz{ int baz_t; }baz_w;

baz_w a;这样毫不犹豫就会报错,这个就像

int a;a b;的错误一致。

猜你喜欢

转载自blog.csdn.net/iloveyou418/article/details/79349784