Bootstrap

【C语言】_类型重命名typedef关键字

目录

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型;

;