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

embedded/2025/1/13 9:45:42/

目录

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


http://www.ppmy.cn/embedded/153521.html

相关文章

Single Agent 阶段性总结

Agent 通常指的是一类具备高度自主性的智能实体&#xff0c;它们能够巧妙地在特定环境里自主感知信息&#xff0c;运用内置的智能算法做出理性决策&#xff0c;进而精准无误地执行相应动作。相较于 RAG&#xff08;检索增强生成&#xff09;技术&#xff0c;Agent 可解决诸多难…

【广西乡镇界】arcgis格式shp数据乡镇名称和编码2020年内容测评

【广西乡镇界】arcgis格式shp数据乡镇名称和编码2020年内容测评

[JavaEE] Spring IoCDI

目录 一、IoC 1.1 IoC 概念 1.2 IoC的作用 二、DI 2.1 DI 概念 2.2 属性注入(Field Injection) 2.3 构造方法注入(Constructor Injection) 2.4 Setter 注入(Setter Injection) 2.5 三种注入优缺点分析 2.5.1 属性注入 2.5.2 构造函数注入 2.5.3 Setter 注入 三、IoC…

【conda】迁移到其他ubuntu机器

想把部署在一台4070机器的conda 环境导出到3090机器查看已安装的环境 conda env list环境导出 conda env export > semantic-text2image-search.yml 4070的conda环境导出 nvidia-smi 命令可以查看 GPU 的基本信息,包括显存、CUDA 驱动版本等: Driver Version:当前 NVIDI…

ros2笔记-6.2 使用urdf创建机器人模型

本节主要跟着小鱼老师的视频操作&#xff0c;不同的仿真平台有不同的建模语言&#xff0c;但是几乎都支持URDF。 本节使用URDF创建一个机器人模型。 6.2.1 帮机器人创建一个身体 URDF使用XML来描述机器人的结构和传感器、执行器等信息。 在chapt6/chap6_ws/src创建功能包:r…

GCC安全编译选项

文章目录 GCC安全编译选项1.BIND_NOW2.NX3.PIC4.PIE5.SP6.NO Rpath/Runpath7.FS8.Ftrapv9.Strip10.安全编译Python GCC安全编译选项 1.BIND_NOW 定义:立即绑定,打开GOT表重定位只读选项 使用方式:LDFlAGS"-Wl,-z,relro,-z,now" ./configure 2.NX 堆栈不可执行:打…

Golang笔记——rune和byte

大家好&#xff0c;这里是Good Note&#xff0c;关注 公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍Golang中的两种字符类型rune和byte&#xff0c;介绍他们的区别&#xff0c;编码方式和简单的使用。 文章目录 byte 类型rune 类型UTF-8 与 Unico…

2024最新版Node.js下载安装保姆级教程【图文详解】

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境&#xff0c;允许开发者在服务器端运行 JavaScript。它以非阻塞、事件驱动的架构处理高并发&#xff0c;适用于构建高效的网络应用。在 APP 自动化测试中&#xff0c;Node.js 常用于构建测试框架&#xff08;如 WebD…