目录
1. 从复杂类型理解类型重命名的必要性
1.1 示例1
1.2 示例2
2. typedef 用法
2.1 简单类型重命名
2.2 复杂指针类型重命名
2.2.1 数组指针类型
2.2.2 函数指针类型
3. 使用typedef简化复杂类型的定义
4. #define与typedef
1. 从复杂类型理解类型重命名的必要性
1.1 示例1
( * (void (*) () ) 0 )();
(1)void (*) ( ) 表示函数指针类型;
注:可通过增加变量名识别:void (*p) ( )表示名为p的函数指针变量;
(2) (void (*) () ) 0 实现将0由原本的整型强制类型转换为函数指针类型;
(3)( * (void (*) () ) 0 ) ( ) 表示调用0地址处的无参且返回值为void的函数;
注:0地址不允许用户程序访问,该行代码运行会抛异常;
1.2 示例2
void ( *signal (int, void(*) (int) ) )(int);
(1)void(*) (int) 表示以一个int型为参数且返回值为void的函数指针变量;
(2)signal (int, void(*) (int) ) 表示两个参数分别为int型和函数指针型的,名为signal的函数;
(3)void (* )(int)表示以一个int型为参数且返回值为void的函数指针变量;
注:挖去(2)中已分析部分,得到void ( * )(int);
(4)void ( *signal (int, void(*) (int) ) )(int) 等价于void (* )(int) signal (int, void(*) (int) ),
(该写法是错误的,但可更直观理解该行代码的功能)
即:声明了一个名为signal的函数,该函数有两个参数,一个为int型,一个为函数指针变量,
并且该函数的返回值也是函数指针类型;
2. typedef 用法
2.1 简单类型重命名
#include<stdio.h>
typedef unsigned int u_int;
typedef int* pint_t;
int main() {// 以下两行等价unsigned int a1;u_int a2;// 以下两行等价int* b1;pint_t b2;return 0;
}
2.2 复杂指针类型重命名
2.2.1 数组指针类型
#include<stdio.h>
typedef int(*pa_t)[5];
int main() {int arr[5] = { 1,2,3,4,5 };int(*pa1)[5] = &arr;pa_t pa2 = &arr;printf("pa1 = %p\n", pa1);printf("pa2 = %p\n", pa2);return 0;
}
运行结果如下:
注:按照标准格式应写为:typedef int(*)[5] pa_t,但对于数组指针类型,需将重命名后的类型名移至括号内的*边:typedef int(*pa_t)[5];
2.2.2 函数指针类型
#include<stdio.h>
typedef int(*pf_t)(int, int);
int Add(int x, int y) {return x + y;
}
int main() {int(*pf1)(int, int) = &Add;pf_t pf2 = &Add;printf("pf1 = %p\n", pf1);printf("pf2 = %p\n", pf2);return 0;
}
运行结果如下:
注:按照标准格式应写为:typedef int(*)(int, int) pf_t,但对于数组指针类型,需将重命名后的类型移至括号内的*边:typedef int(*pf_t)(int, int);
3. 使用typedef简化复杂类型的定义
(回归示例1与示例2,对应简化)
#include<stdio.h>
typedef void(*pf_t)();
int main() {// ( * (void (*) () ) 0 )();((pf_t)0)();// void ( *signal (int, void(*) (int) ) )(int);pf_t signal(int, pf_t);return 0;
}
4. #define与typedef
#include<stdio.h>
#include<stdlib.h>
typedef int* pint_t;
#define PINT_T int*
int main() {pint_t p1, p2;// p1 p2都是指针变量PINT_T p3, p4;// p3是指针变量,p4是整型变量return 0;
}
调试借助监视窗口查看变量类型:
理解#define与typedef的区别:
(1)int*一经typedef为pint_t,所有int*会被替换为int*:
pint_t p1, p2;// 即处理为:// int* p1; int* p2;
(2)#define仅仅实现了符号PINT_T等价为int*:
PINT_T p3, p4;// 即处理为:// int* p3,p4;// 即:int *p3; int p4;
仅将*分配给p3,即将p3定义为int*型,p4定义为int型;