typedef的四个用途和两个陷阱
---------------------------------

用途一:
定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:
char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针,
// 和一个字符变量;
以下则可行:
typedef char* PCHAR; // 一般用大写
PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针
虽然:
char *pa, *pb;
也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。

用途二:
用在旧的C的代码中(具体多旧没有查),帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名 对象名,如:
struct tagPOINT1
{
int x;
int y;
};
struct tagPOINT1 p1;

而在C++中,则可以直接写:结构名 对象名,即:
tagPOINT1 p1;

估计某人觉得经常多写一个struct太麻烦了,于是就发明了:
typedef struct tagPOINT
{
int x;
int y;
}POINT;

POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候

或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。

用途三:
用typedef来定义与平台无关的类型。
比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:
typedef long double REAL;
在不支持 long double 的平台二上,改为:
typedef double REAL;
在连 double 都不支持的平台三上,改为:
typedef float REAL;
也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。
标准库就广泛使用了这个技巧,比如size_t。
另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。

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

1. 原声明:int *(*a[5])(int, char*);
变量名为a,直接用一个新别名pFun替换a就可以了:
typedef int *(*pFun)(int, char*);
原声明的最简化版:
pFun a[5];

2. 原声明:void (*b[10]) (void (*)());
变量名为b,先替换右边部分括号里的,pFunParam为别名一:
typedef void (*pFunParam)();
再替换左边的变量b,pFunx为别名二:
typedef void (*pFunx)(pFunParam);
原声明的最简化版:
pFunx b[10];

3. 原声明:doube(*)() (*e)[9];
变量名为e,先替换左边部分,pFuny为别名一:
typedef double(*pFuny)();
再替换右边的变量e,pFunParamy为别名二
typedef pFuny (*pFunParamy)[9];
原声明的最简化版:
pFunParamy e;

理解复杂声明可用的“右左法则”:
从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直到整个声明分析完。举例:
int (*func)(int *p);
首先找到变量名func,外面有一对圆括号,而且左边是一个*号,这说明func是一个指针;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明(*func)是一个函数,所以func是一个指向这类函数的指针,即函数指针,这类函数具有int*类型的形参,返回值类型是int。
int (*func[5])(int *);
func右边是一个[]运算符,说明func是具有5个元素的数组;func的左边有一个*,说明func的元素是指针(注意这里的*不是修饰func,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合)。跳出这个括号,看右边,又遇到圆括号,说明func数组的元素是函数类型的指针,它指向的函数具有int*类型的形参,返回值类型为int。

也可以记住2个模式:
type (*)(....)函数指针
type (*)[]数组指针
---------------------------------

陷阱一:
记住,typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如:
先定义:
typedef char* PSTR;
然后:
int mystrcmp(const PSTR, const PSTR);

const PSTR实际上相当于const char*吗?不是的,它实际上相当于char* const。
原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。
简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。

陷阱二:
typedef在语法上是一个存储类的关键字(如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如:
typedef static int INT2; //不可行
编译将失败,会提示“指定了一个以上的存储类”。

typedef的四个用途和两大陷阱相关推荐

  1. typedef 的四个用途和两大陷阱

    >>>>>用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如: char* pa, pb; // 这多数不符合我们的意图,它只声明 ...

  2. typedef的四个用途和两个陷阱

    typedef的四个用途和两个陷阱 --------------------------------- 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如: c ...

  3. 马云最新分析:未来3年投资四万从事这两大行业,一年后年入百万

    马云最新分析:未来3年投资四万从事这两大行业,一年后年入百万 马云说:努力奋斗,不去做,永远不会有收获:不相信,永远不会有成功:不可能,永远只能停留在现在:未来,是靠把握机会和努力奋斗.不管生活多么的 ...

  4. MySQL中处理Null时要注意两大陷阱

    MySQL中处理Null时要注意两大陷阱 摘要:作为MySQL数据库管理员,我们经常要与Null做斗争.但是在这其中,你需要注意一下两大陷阱. MySQL数据库是一个基于结构化数据的开源数据库.SQL ...

  5. mysql null处理_MySQL中处理Null时要注意两大陷阱

    MySQL数据库是一个基于结构化数据的开源数据库.SQL语句是MySQL数据库中核心语言.不过在MySQL数据库中执行SQL语句,需要小心两个陷阱. 陷阱一:空值不一定为空 空值是一个比较特殊的字段. ...

  6. AB testing之两大陷阱

    今天主要讲讲 primacy effect & novelty effect 在 AB testing中产生的陷阱 背景知识: 什么是Ab Testing? 当遇到典型的产品或工程组织时,团队 ...

  7. 警惕稻盛和夫热的两大陷阱

    稻盛哲学和阿米巴可以学习,但不必迷信,世界上没有一招致胜的"葵花宝典". 某集团企业A事业部在咨询专家精心辅导下,精益管理做得有声有色,员工参与度不断提高,第一年就取得了丰硕成果, ...

  8. 商汤科技举办病理、放疗两大MICCAI国际挑战赛,推动AI医疗落地

    近日,商汤科技宣布将联合衡道病理.上海交通大学医学院附属瑞金医院.西京医院.上海市松江区中心医院举办MICCAI 2019消化道病理图像检测与分割国际挑战赛,联合医诺智能科技.浙江省肿瘤医院举办MIC ...

  9. 苹果首任AI总监Ruslan Salakhutdinov:如何应对深度学习的两大挑战?(附视频)

    虽然用AI算法可以解决很多问题,但当前还是面临很多局限性和挑战.卡内基梅隆大学教授.苹果首任AI总监Ruslan Salakhutdino认为,当前面对的挑战主要分为以下四大类: 1) 自然语言理解与 ...

最新文章

  1. CF1397B Power Sequence(大胆枚举)
  2. python udp创建addr_python高级:8.socket通信part1
  3. SM02 发送系统消息给所有Client用户
  4. 迄今为止用到的Eclipse快捷键,最常用的--[欢迎补充]
  5. 仿生蠕虫机器人制作步骤_鸭子机器人领衔,盘点2019年上半年那些有趣的仿生机器人...
  6. 技术随想--不求安稳,超越自我
  7. 51nod1417 天堂里的游戏
  8. python 调用大漠
  9. java图书销售系统_基于Java Web的图书销售管理系统
  10. linux df -hl 数据解释,linux磁盘空间查看命令(du,df)剩余空间查看详解
  11. 小谈国内桌面浏览器占有率
  12. 慕课moocpython答案_中国大学慕课moocPython编程基础作业答案
  13. APP下载量全面概述,含统计方法
  14. 通过函数名称字符串发起调用/函数名反射
  15. 回炉再造Css Layout
  16. 一段神奇的代码-关于PHP字符变量奇怪现象的解释
  17. Linux 脚本后台执行
  18. Windows下编译FFmpeg 32位和64位DLL
  19. Avada学习之-如何修改Header-logo和favicon图标
  20. 开发人员必备电子书下载

热门文章

  1. c语言表达式3178的值为,【C语言】C语言运算符
  2. c语言枚举3位数相加等于10,C语言 联合和枚举
  3. linux 多目录makefile,royalchen
  4. npm 安装less插件_2020 VSCode插件推荐
  5. Java Spring @Scheduled 定时任务crontab表达式设置
  6. POJ - 3417 Network LCA+树上差分
  7. Matlab人脸检测算法详解
  8. 戴尔服务器重装系统优盘启动不了怎么办,U盘重装系统,开机按F12选择USB启动项无法进入PE系统怎么办?...
  9. centos7 mysql workbench_centOS下mysql workbench安装配置教程
  10. 【全网之最】全网最短代码——给名字、电话、账号、昵称加星号*添加隐私保护、身份证号加密、信息脱敏