【C】C的typedef的妙用

1.自定义数组类型

1
typedef int (Array)[5];

Array是一个类型为int长度为5的数组类型,即定义一个Array a;那么a就是一个类型为int长度为5的数组,所以a的使用方法和数组一致。

1
2
3
4
5
6
7
typedef int(Array)[5];
Array a;
int i = 0,j = 0;
for (i = 0; i < 5; i++)
a[i] = i;
for (j = 0; j < 5; j++)
printf("%d,", a[j]);

2.自定义指向数组的指针类型

1
typedef char(*Arrayptr)[8];

Arrayptr是一个指向char类型的长度为8的数组的指针类型,此类型的指针只能指向char类型的长度为8的数组。且每一次指针移步,移动的距离是1*8=8字节。

需要注意的是()不能省略,否则定义就会变义。

除了自定义指针类型来指向一个固定的数组外,C还可以直接定义一个指向固定数组的指针变量。

1
int (*p)[5];

p就是一个指向类型为整型且长度为5的数组的指针变量。

3.自定义函数类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef int (Funptr)(int a, int b);//函数类型
int Fun1(int a, int b)
{
return a + b;
}
void Fun2(Funptr *p)
{
printf("%d\n", p(1, 2));
}
int main()
{
Funptr *p = &Fun1;
Fun2(p);
system("pause");
return 0;
}

Funptr是一个指向返回值为int参数列表为int,int的函数的类型,通过Funptr函数类型的指针可以将返回值为int参数列表为int,int的函数当作参数来使用,使函数的调用更为灵活。

除了定义函数类型可以达到这种效果,我们还可以直接定义指向函数的指针类型来实现函数参数化,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef int (*Funptr)(int a, int b);
int Fun1(int a, int b)
{
return a + b;
}
void Fun2(Funptr p)
{
printf("%d\n", p(1, 2));
}
int main()
{
Funptr p = &Fun1;
Fun2(p);
system("pause");
return 0;
}

这样的效果和定义函数类型是一样的。

当然我们还可以直接定义一个指向函数的指针变量,来实现同样的效果,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int Fun1(int a, int b)
{
return a + b;
}
void Fun2(Funptr p)
{
printf("%d\n", p(1, 2));
}
int main()
{
int(*p)(int a, int b) = &Fun1;
Fun2(p);
system("pause");
return 0;
}

我们还可以这么做,一样能达到相同的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int Fun1(int a, int b)
{
return a + b;
}
void Fun2(int (*ptr)(int a,int b))//直接定义函数指针的形参
{
printf("%d\n", ptr(1, 2));
}
int main()
{
Fun2(&Fun1);//直接传递函数地址
system("pause");
return 0;
}

搞了那么多似乎函数指针只是把函数的调用弄得更复杂了而已,除了把函数当作参数来使用似乎没有什么作用了,真的是如此吗?

 如果我们仔细观察,会发现函数指针将函数的调用和函数的实现分隔开来了,即函数指针提前规定好了函数的实现标准,这样只要后来者按照这个标准来实现函数,可以不用修改前人的代码,就能实现函数的完美的调用,这一作用在具体的项目迭代中是及其出众的。