前言
最近准备开始总结一些东西,当遇到C语言中的typedef
时,回想起当时学的时候遇到了一些误区,这里分享出来供大家参考。
typedef可能导致的误区
在我们初学的时候,无非就是类似像下面这样使用typedef
关键字。
#include <stdio.h>
typedef int INT;
typedef struct test
{
int a;
int b;
}Test;
int main()
{
...
}
可能久而久之就将其理解为typedef
就是替前面的类型声明一个别名而已。
但是当我们看到这样的用法typedef void (*FUNC)(int)
,其中void (*FUNC)(int)
是一个函数指针,可能再按照上面前后关系这种思维就无法明白这条语句到底干了什么,是将void
声明成(*FUNC)(int)
?还是将void (*FUNC)
声明成(int)
?其实都不是。看下面的一个简单样例。
#include <stdio.h>
typedef void (*FUNC)(int);
void test(int num)
{
printf("%d\n", num);
return;
}
int main()
{
int num = 1;
FUNC print_num = test;
print_num(num);
return 0;
}
对比不使用typedef
关键字时:
#include <stdio.h>
void (*func)(int);
void test(int num)
{
printf("%d\n", num);
return;
}
int main()
{
int num = 1;
func = test;
func(num);
return 0;
}
正确的理解
首先我们再回到最初那个例子,typedef int INT;
,当我们去掉typedef
时,为int INT;
,这是一个普通的声明变量的语句;而去掉typedef struct test { int a; int b; }Test;
中的typedef
时,为struct test { int a; int b; }Test;
,相当于声明了一个类型为struct test
的变量Test
。
当我们加上typedef
时,原本语句声明的变量变成了该变量类型的别名。
有了这样的认知,我们再回到typedef void (*FUNC)(int)
这条语句上,在上面的例子中,去掉typedef
后是void (*FUNC)(int)
,相当于声明了一个函数指针,加上了typedef
即代表给void (*)(int)
这样一个函数指针类型声明了一个别名叫做FUNC
。
事实上,这样的做法也是信号机制中信号捕捉函数sighandler_t signal(int, sighandler_t)
的做法,sighandler_t
为typedef void (*sighandler_t)(int)
。
下面再给出一个例子帮助理解:
#include <stdio.h>
typedef int ARRAY[20];
int main()
{
ARRAY a;
printf("%d\n", sizeof(a));
return 0;
}
如果你认为输出是4
,那你可能还没有理解。此时的变量a
已经是一个长度为20
的整型数组了。