关于typedef的用法总结

2023-11-04

typedef的应用

typedef是C 语言中用于为现有数据类型指定替代名称的关键字。它主要用于用户定义的数据类型,当数据类型的名称在程序中使用变得稍微复杂时。以下是使用的一般语法

typedef <existing_name> <alias_name>

应用一:结构体别名

typedef也可用于为用户定义的数据类型命名。让我们看看它对结构体的使用。

// ======== old
struct type_name
{
    type member1;
    type member2;
    type member3;
};
struct type_name name;

// ========== 分割线
typedef struct
{
    type member1;
    type member2;
    type member3;
} type_name;
type_name name; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候

应用二:类型别名

定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。例如:

int* x, y;

通过这个声明语句,我们实际上声明一个类型为int的指针x,而y则任然声明为一个普通int变量。但是如果我们typedef像在上面的例子中使用的那样使用,我们可以在单个语句中声明任意数量的指针。

typedef int* IntPtr;
IntPtr x, y, z;

但是,有一点需要注意的是,类型别名是别名,但不是全等。例如

typedef int* intptr;
const intptr x; // x是一个const pointer,指向int

不等同于:

const int *x; // x是一个指针,指向const int

intptr是指向 int 的指针。const intptr 是一个const pointer 指向 int, 而不是指向 const int。所以,在 typedef pointer 之后,不能再让它成为content的常量了?即x++将报错。

其相当于:

int * const x;

在标准库中也有些丑陋的实现,比如 gcc 的typeof 宏:

typedef int* intptr;
intptr dummy;
const typeof(*dummy) *x;

应用三:适配解耦

比如定义一个叫 REAL 的浮点类型,在系统Platform A上,让它表示最高精度的类型为:

typedef long double REAL;

在不支持 long double 的系统Platform B上,改为:

typedef double REAL;

在连 double 都不支持的系统Platform C上,改为:

typedef float REAL;

也就是说,当跨平台时,只要改下 typedef 本身就行,或者使用宏开关控制即可,将对应类型与平台解耦。

#ifdef PlatformA
	typedef long double REAL;
#elseif Platform B
	typedef double REAL;
#elseif Platform C
	typedef float REAL;
#else
	typedef void REAL;
#endif

标准库就广泛使用了这个技巧,比如size_t。

应用四:代码灵活性

为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。举两个例子:

  • 原声明一:
void (*b[10]) (void (*)());

变量名为b,先替换右边部分括号里的,pFunParam为别名一:

typedef void (*pFunParam)();

再替换左边的变量b,pFunx为别名二:

typedef void (*pFunx)(pFunParam);

原声明的最简化版:

pFunx b[10];
  • 原声明二:
doube(*)() (*e)[9];

变量名为e,先替换左边部分,pFuny为别名一:

typedef double(*pFuny)();

再替换右边的变量e,pFunParamy为别名二

typedef pFuny (*pFunParamy)[9];

原声明的最简化版:

pFunParamy e;

理解复杂声明可用的“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直到整个声明分析完。

另外,void*在C语言作为万能指针,因为C中的非强耦合,很多时候利用其强转保持代码的复用性、灵活性, 声明为用户类型和用户指针类型也稍许不同,但本质都计算地址偏移。

#ifdef __cplusplus

extern "C" {
    #include <stdio.h>

    typedef void (CbkFuncPoint)(int i, int j); // void

    void (*CbkFunc)(int i, int j); // void *
    typedef void (*CbkFuncVar)(int i, int j); // void *


    struct TestStru {
        int id;
        void *func;
    };

    void testCbk(int i, int j)
    {
        printf("TestCbk %d\n", i+j);
    }

    void testCbk2(int i, int j, int k)
    {
        printf("TestCbk2 %d\n", i+j);
        (void)k;
    }

    int main()
    {
    #if 1
        CbkFunc = &testCbk;
        testCbk(0, 10);
        ((CbkFuncPoint*)testCbk)(0, 10);

        CbkFuncPoint *FuncPoint;
        FuncPoint = testCbk;
        FuncPoint(0, 10);

        CbkFuncVar FuncVar;
        FuncVar = &testCbk;
        FuncVar(0, 10);
    #endif

        struct TestStru struvar = {
            10, (void *)testCbk
        };

        (*((CbkFuncPoint*)struvar.func))(10, 20);
        ((CbkFuncPoint*)struvar.func)(10, 20);
        (*((CbkFuncPoint*)testCbk))(30, 40); // (void(*)(int, int))&testCbk
        (*((CbkFuncPoint*)testCbk2))(30, 40); // 参数不一致的特殊情况也能强转匹配

        void *tt = (void *)testCbk;
        ((CbkFuncPoint*)tt)(40, 50);

        return 0;
    }
}

#endif

参考资料

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于typedef的用法总结 的相关文章

  • [原]Pro*C介绍-内嵌SQL

    Translate by Z Jingwei Document address http www db stanford edu ullman fcdb oracle or proc html Pro C介绍内嵌SQL 概要 Pro C语法
  • android通过JNI用C/C++创建本地文件

    通过jni在本地创建文件 1 在android studio创建基本的jni工程 并且在APP界面成功显示 Hello from C 不会的可以看android studio使用jni 2 在native lib cpp文件中创建文件 为了
  • 详解原码、反码、补码——深入理解补码

    学过计算机原理的人都知道原码 反码 补码 但是有多少人知道为什么会有这三种码呢 这三种码又是用来干嘛的呢 众所周知 在计算机的世界只有01 那么显然所有的数都得转成二进制 这样计算机才能够理解 如何将一个十进制的数转成二进制就不说了 说下原
  • C语言pcre库的使用及验证IP地址的合法性

    PCRE是一个用C语言编写的正则表达式函数库 它十分易用 同时功能也很强大 性能超过了POSIX正则表达式库和一些经典的正则表达式库 在使用PCRE库时 首先肯定是需要安装pcre的 不过一般的系统都会有自带的PCRE库 不过如果想使用最新
  • Vc/MFC中自定义消息及其PostMessage触发使用

    http blog csdn net ztz0223 article details 2058402 http blog csdn net a8082649 article details 7733527 http bbs csdn net
  • C++工程师复习题

    一 auto ptr 类使用必须满足下列限制 1 不要使用 auto ptr 对象保存指向静态分配对象的指针 2 不要使用两个 auto ptrs 对象指向同一对象 3 不要使用 auto ptr 对象保存指向动态分配数组的指针 4 不要将
  • 大端模式和小端模式转化

    在工作中遇到一个问题 数据是以大端模式存储的 而机器是小端模式 必须进行转换 否则使用时会出问题 一 定义 大端模式 Big Endian 数据的高字节 保存在内存的低地址中 数据的低字节 保存在内存的高地址中 小端模式 Little En
  • Lua和C++交互总结(很详细)

    出处 http blog csdn net shun fzll article details 39120965 一 lua堆栈 要理解lua和c 交互 首先要理解lua堆栈 简单来说 Lua和C c 语言通信的主要方法是一个无处不在的虚拟
  • ATL字符串转换宏

    有比MultiByteToWideChar和WideCharToMultiByte更简单的字符串转换宏 你相信吗 头文件 d program files microsoft visual studio 8 vc atlmfc include
  • mfc窗口创建的create与oncreate

    在view类中 create 是虚函数由框架调用 是用来 生成一个窗口的子窗口 oncreate 消息响应函数 是用来 表示一个窗口正在生成 某个CWnd的Create函数由当前CWnd的Owner调用 而在CWnd Create中 又会调
  • 检查内存泄露

    自己编写的视频处理程序出现了一个问题 每帧的运行时间随着运行时间在不断增长 很大可能是出现了内存泄露 于是学习了一些查看内存泄露的方法 做了两种尝试 一是VS自带的DEBUG下的检测 view pl html view plain copy
  • 一个简单的参数帮助框架,c实现

    文章目录 具体实现如下 include
  • enable_shared_from_this使用介绍

    文章目录 enable shared from this定义 使用场合 源码实现 注意 enable shared from this定义 定义于头文件 template lt class T gt class enable shared
  • C 语言教程:数据类型和格式说明符

    C 语言中的数据类型 C 中的变量必须是指定的 数据类型 并且您必须在 printf 函数中使用 格式说明符 来显示它 创建变量 int myNum 5 整数 没有小数点 float myFloatNum 5 99 浮点数 char myL
  • C/C++编程:令人印象深刻的高级技巧案例

    C C 编程语言在软件开发领域有着悠久的历史 由于其高效 灵活和底层访问能力 至今仍然被广泛应用 本文将介绍一些在C C 编程中令人印象深刻的高级技巧 帮助读者提升编程水平 更加高效地使用这两种强大的编程语言 一 指针运算与内存管理 C C
  • C/C++编程:令人印象深刻的高级技巧案例

    C C 编程语言在软件开发领域有着悠久的历史 由于其高效 灵活和底层访问能力 至今仍然被广泛应用 本文将介绍一些在C C 编程中令人印象深刻的高级技巧 帮助读者提升编程水平 更加高效地使用这两种强大的编程语言 一 指针运算与内存管理 C C
  • C++ 字符串比较------strcmp函数和strncmp函数

    strcmp 函数原型 int strcmp const char str1 const char str2 功能 strcmp函数会按照字典顺序逐个比较两个字符串的字符 直到遇到不同的字符或者遇到字符串结束符 0 返回值 该函数返回值如下
  • C 语言文件读取全指南:打开、读取、逐行输出

    C 语言中的文件读取 要从文件读取 可以使用 r 模式 FILE fptr 以读取模式打开文件 fptr fopen filename txt r 这将使 filename txt 打开以进行读取 在 C 中读取文件需要一点工作 坚持住 我
  • C++ 中 const 和 constexpr 关键字解析:常量、函数和指针

    很多 C 的初学者看到 const 这个关键字的第一反应都是一头雾水 主要是因为 const 可 以出现在很多的位置 以及后面加入的 constexpr 更是常常感到困惑 今天就为大家一一解释出现它们的含义和以及作用 const 关键字 c
  • 在 OS X 上的 virtualenv 中安装 scrapy 加密时发生错误 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在安装 scrapypip in virtualenv on OS X 10 11 当它安装密码学时 它说 buil

随机推荐

  • Proteus实现555计时器模拟简易电子琴

    555计时器模拟简易电子琴 一 元器件介绍 二 原理分析 三 仿真实验 实现弹奏过程 一 元器件介绍 这里用到的元器件有 RESISTOR 电阻器 CAP 电容器 BUTTON 按钮 555 555计时器 BUZZER ACTIVE 有源蜂
  • Nacos 搭建和使用

    说明 官方文档 https nacos io zh cn docs what is nacos html 粘贴一下Nacos地图 逻辑架构及其组件介绍 服务管理 实现服务CRUD 域名CRUD 服务健康状态检查 服务权重管理等功能 配置管理
  • 4G网关8305LN远程监控西门子触摸屏SMART 700IE ZLAN8305LN应用

    1 概述 ZLAN8305LN是一款专门为工业环境设计的RS485设备数据采集器 物联网网关 他通过4G的方式传输 结合卓岚特有的P2P技术 无需构建公网服务器也可以同样随时随地采集设备的数据 本次案例主要是实现目的 对SMART700IE
  • 涉及Radio传值的写法

    博主最近在帮朋友做毕设 需要新增一个功能 功能里面有个radio列表 需要传radio元素的id值到后台 尝试了好多种写法都不行 最后用了下面的写法就好 后台顺利接收到参数 话不多说 直接上图 要如图红框里面的写法才能取到被选中的选项ID的
  • Mysql8.0的安装与配置(图文超详细)

    MySQL8 0安装配置 1 软件下载 2 软件安装 3 软件配置 4 环境变量配置 1 软件下载 链接 https pan baidu com s 1gyNz1o7SCyLIfoNcBUKRIQ 提取码 ajpl 2 软件安装 1 下载好
  • vue 收藏和取消收藏的点击事件

    描述 点击 取消收藏 图标切换 文字变为 收藏 收藏状态变为 未收藏 刷新页面 未收藏 数据不再显示 思路 通过if判断 给定这条数据一个状态 点击改变状态值 状态需要后端在接口里返回 未点击时 图标亮 状态为true 点击时 图标灰 数据
  • Qt 自定义数据类型在信号和槽中的传递

    Qt 信号和槽函数参数只能是基于 Qt 的基础类型的 比如 QString int bool 等 如果想传递自定义类型默认情况下是行不通的 下面以结构体为例 实现结构体类型数据的传递 头文件 ifndef MAINWINDOW H defi
  • 可视化分组散点图并添加分层线性回归模型的拟合曲线(使用R语言)

    可视化分组散点图并添加分层线性回归模型的拟合曲线 使用R语言 在数据分析和可视化中 经常需要绘制散点图以观察两个变量之间的关系 并使用回归模型来拟合数据 本文将介绍如何使用R语言创建分组散点图 并添加分层线性回归模型的拟合曲线 首先 我们需
  • 【操作系统】王道考研 p50-51 文件的物理结构(文件分配方式)

    文件的物理结构 上 文件的物理结构 下 知识总览 文件块 磁盘块 磁盘块的大小与内存块 页面的大小相同 内存与磁盘之间的数据交换以 块 为单位 在外存管理中 文件的逻辑地址空间被分为一个个文件块 连续分配 连续分配要求每个文件在磁盘上占有一
  • Integer的缓存机制、自动装箱拆箱

    一 什么是自动装箱拆箱 很简单 下面两句代码就可以看到装箱和拆箱过程 自动装箱 Integer total 99 自动拆箱 int totalprim total 简单一点说 装箱就是自动将基本数据类型转换为包装器类型 拆箱就是自动将包装器
  • 五行中的土在哪个方位_五行代表的方位

    五行方位 东 南 中 西 北 论 五 行 生 成 五行是构成宇宙万物的五种元素 它们是变化无穷 高深莫测的 五行的创立 準确地模拟了自然界的状态 宇宙万物的生息变化都不能离开五行 五行的顺序 一水 二火 叁木 四金 五土 这个顺序列取决于地
  • go性能优化

    常规手段 1 sync Pool 临时对象池应该是对可读性影响最小且优化效果显著的手段 最典型的就是fasthttp了 它几乎把所有的对象都用sync Pool维护 但这样的复用不一定全是合理的 比如在fasthttp中 传递上下文相关信息
  • 【故障诊断】基于最小熵反卷积、最大相关峰度反卷积和最大二阶环平稳盲反卷积等盲反卷积方法在机械故障诊断中的应用研究(Matlab代码实现)

    个人主页 研学社的博客 欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 稀疏最大谐波噪声比反卷积 2 2 最大相关峰度反卷积 2 3
  • 认知计算导论自救版笔记

    认知计算导论 认知数据收集 认知cognitive数据 1 定义 认知物联网IoT 认知系统和互联网组合 认知数据来源 物理世界 互联网提供大量数据 虚拟世界 社交网络和移动计算 人群感知Crowd Sensing 大量人群通过移动设备无意
  • vst开启语音服务器,VST语音遥控器体验记

    体验信息 101245hu4k1a42krae4l4s jpg 10 39 KB 下载次数 5 2015 5 30 16 34 上传物品名称 VST智能语音遥控器适配物品 101502huualwallumcbaaa jpg 3 35 KB
  • 基于数组的链表AList

    快考试了 作为数据结构的复习 那么就把代码背打一遍好了 虽然代码很简单 但是把基础打牢固对以后的学习肯定是百益而无一害 正好也练练C 模板和指针以及代码书写的模块化 否则天天写些算法程序 一写就一大坨 乱乱的 养成习惯就悲剧了 看一点写一点
  • 梅尔频率倒谱系数(MFCC)

    https blog csdn net zkl99999 article details 80723755
  • winform中如何设置splitContainer中panel的宽度,并在以后的拖动中保持不变

    搜先随便选着一个penel 按Esc键这时你会选择这个splitContainer控件 假如 你要固定penel1 这时你需要先拖动splitContainer控件 让penel1全部显示出来 然后在splitContainer控件的属性中
  • 一、Gradle入门

    文章目录 一 Gradle入门 1 1 Gradle 简介 1 2 常见的项目构建工具 1 3 Gradle 安装 1 3 1 Gradle 安装说明 1 3 2 安装 JDK 1 3 3 下载并解压到指定目录 1 3 4 配置环境变量 1
  • 关于typedef的用法总结

    typedef的应用 typedef是C 语言中用于为现有数据类型指定替代名称的关键字 它主要用于用户定义的数据类型 当数据类型的名称在程序中使用变得稍微复杂时 以下是使用的一般语法 typedef