typedef
第一、四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如: 用途二: 用在旧的C的代码中(具体多旧没有查),帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名 对象名,如: 而在C++中,则可以直接写:结构名 对象名,即: 估计某人觉得经常多写一个struct太麻烦了,于是就发明了: POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候 或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。 用途三: 用typedef来定义与平台无关的类型。 用途四: 为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。举例: 1. 原声明:int *(*a[5])(int, char*); 2. 原声明:void (*b[10]) (void (*)()); 3. 原声明:doube(*)() (*e)[9]; 理解复杂声明可用的“右左法则”: 也可以记住2个模式: 第二、两大陷阱 陷阱一: 记住,typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如: const PSTR实际上相当于const char*吗?不是的,它实际上相当于char* const。 陷阱二: typedef在语法上是一个存储类的关键字(如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如: 以上资料出自:http://blog.sina.com.cn/s/blog_4826f7970100074k.html 作者:赤龙 第三、typedef 与 #define的区别 案例一: 通常讲,typedef要比#define要好,特别是在有指针的场合。请看例子: typedef char *pStr1; #define pStr2 char *; pStr1 s1, s2; pStr2 s3, s4; 在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。 案例二: 下面的代码中编译器会报一个错误,你知道是哪个语句错了吗? typedef char * pStr; char string[4] = "abc"; const char *p1 = string; const pStr p2 = string; p1++; p2++; 是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。 第四部分资料:使用 typedef 抑制劣质代码 作者:Danny Kalev 原文出处:Using typedef to Curb Miscreant Code 摘要:Typedef 声明有助于创建平台无关类型,甚至能隐藏复杂和难以理解的语法。不管怎样,使用 typedef 能为代码带来意想不到的好处,通过本文你可以学习用 typedef 避免缺欠,从而使代码更健壮。 typedef 声明,简称 typedef,为现有类型创建一个新的名字。比如人们常常使用 typedef 来编写更美观和可读的代码。所谓美观,意指 typedef 能隐藏笨拙的语法构造以及平台相关的数据类型,从而增强可移植性和以及未来的可维护性。本文下面将竭尽全力来揭示 typedef 强大功能以及如何避免一些常见的陷阱。 Q:如何创建平台无关的数据类型,隐藏笨拙且难以理解的语法? A: 使用 typedefs 为现有类型创建同义字。 定义易于记忆的类型名 typedef int size; 此声明定义了一个 int 的同义字,名字为 size。注意 typedef 并不创建新的类型。它仅仅为现有类型添加一个同义字。你可以在任何需要 int 的上下文中使用 size: void measure(size * psz); size array[4];size len = file.getlength();std::vector <size> vs; typedef 还可以掩饰符合类型,如指针和数组。例如,你不用象下面这样重复定义有 81 个字符元素的数组: char line[81];char text[81]; 定义一个 typedef,每当要用到相同类型和大小的数组时,可以这样: typedef char Line[81]; Line text, secondline;getline(text); 同样,可以象下面这样隐藏指针语法: typedef char * pstr;int mystrcmp(pstr, pstr); 这里将带我们到达第一个 typedef 陷阱。标准函数 strcmp()有两个‘const char *’类型的参数。因此,它可能会误导人们象下面这样声明 mystrcmp(): int mystrcmp(const pstr, const pstr); 这是错误的,按照顺序,‘const pstr’被解释为‘char * const’(一个指向 char 的常量指针),而不是‘const char *’(指向常量 char 的指针)。这个问题很容易解决: typedef const char * cpstr; int mystrcmp(cpstr, cpstr); // 现在是正确的 记住:不管什么时候,只要为指针声明 typedef,那么都要在最终的 typedef 名称中加一个 const,以使得该指针本身是常量,而不是对象。 代码简化 typedef int (*PF) (const char *, const char *); 这个声明引入了 PF 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。如果要使用下列形式的函数声明,那么上述这个 typedef 是不可或缺的: PF Register(PF pf); Register() 的参数是一个 PF 类型的回调函数,返回某个函数的地址,其署名与先前注册的名字相同。做一次深呼吸。下面我展示一下如果不用 typedef,我们是如何实现这个声明的: int (*Register (int (*pf)(const char *, const char *))) (const char *, const char *); 很少有程序员理解它是什么意思,更不用说这种费解的代码所带来的出错风险了。显然,这里使用 typedef 不是一种特权,而是一种必需。持怀疑态度的人可能会问:“OK,有人还会写这样的代码吗?”,快速浏览一下揭示signal()函数的头文件 <csinal>,一个有同样接口的函数。 typedef 和存储类关键字(storage class specifier) typedef register int FAST_COUNTER; // 错误 编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号 typedef 已经占据了存储类关键字的位置,在 typedef 声明中不能用 register(或任何其它存储类关键字)。 促进跨平台开发 typedef long double REAL; 在不支持 long double 的机器上,该 typedef 看起来会是下面这样: typedef double REAL; 并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样: 、 typedef float REAL; |
typedef的更多相关文章
- 19-typedef
本文目录 一.typedef作用简介 二.typedef与指针 三.typedef与结构体 三.typedef与指向结构体的指针 四.typedef与枚举类型 五.typedef与指向函数的指针 六. ...
- #define与typedef在重定义类型中的区别
#define 为完全的替换 typedef 重新定一个数据类型 eg #define charp1 char* typedef char* charp2charp1 a,b; //a char* b ...
- 用typedef定义函数指针的问题
在学习windows API的时候,遇到下面这段代码 以前见过的typedef的用法都是给一个数据类型取一个别名 typedef oldTypeName newTypeName 这种给数据类型 ...
- C语言语法 typedef小结
在总结typedef之前,先了解一个专业术语: 常量指针(const pointer):常量指针在定义的时候必须被初始化,而且一旦初始化完成,则它的值就不能再改变. int errNumb = 0; ...
- 如何理解typedef void (*pfun)(void)
问题: 在刚接触typedef void (*pfun)(void) 这个结构的时候,存在疑惑,为什么typedef后只有一"块"东西,而不是两"块"东西呢?那 ...
- C及C++中typedef的简单使用指南
又是在学数据结构的时候,发现了之前学习的知识遗忘很多,在发现对C/C++中关键字typedef的理解还是没有到位后,我翻阅了学C++用到的课本,又问了度娘,也看了不少关于typedef用法的博客.于是 ...
- [转]关于typedef的用法总结
不管实在C还是C++代码中,typedef这个词都不少见,当然出现频率较高的还是在C代码中.typedef与#define有些相似,但更多的是不同,特别是在一些复杂的用法上,就完全不同了,看了网上一些 ...
- typedef 和 #define 的区别
本文已迁移至: http://www.danfengcao.info/c/c++/2014/02/25/difference-between-define-and-typedef.html typed ...
- [转载]彻底弄清struct和typedef struct
struct和typedef struct 分三块来讲述: 1 首先://注意在C和C++里不同 在C中定义一个结构体类型要用typedef: typedef struct Student { int ...
随机推荐
- jQuery+CSS3文字跑马灯特效
jQuery+CSS3文字跑马灯特效是一款将跑马灯背景制作为3D立方体效果,文字在上面移动时,就像是文字投影到墙壁上,在转角出会改变运动方向. 效果展示 http://hovertree.com/te ...
- 征途 bzoj 4518
征途(1s 256MB)journey [问题描述] Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天 ...
- Spring在web应用中获得Bean的方法
一:使用ApplicationContext获得Bean 首先新建一个类,该类必须实现ApplicationContextAware接口,改接口有一个方法,public void setApplica ...
- 《分布式事务解决之道》沙龙ppt共享
大型分布式系统往往由很多“微服务”组成,而不同的微服务往往又连接着不同的数据库,在看似常用的功能背后,可能又需要横跨不同的“微服务”和“数据库”才能实现.那么如何才能保证系统事务的一致性呢?这也同时是 ...
- django 1.10 CSRF验证失败的解决过程
最近工作闲,没事自学django,感觉这个最烦的就是各版本提供的api函数经常有变化,不是取消了就是参数没有了,网上搜到的帖子也没说明用的是什么版本的django,所以经常出现搬运过来的代码解决不了问 ...
- SEED信息安全实验系列:缓冲区溢出漏洞实验
缓冲区溢出漏洞实验 本课程详细出自http://www.shiyanlou.com/courses/231,转载请注明出处. 一.实验描述 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情 ...
- Linux-学习前言
本随笔会持续,不定期更新.我有上网找与Linux相关的博客,发现很多人只写了几篇就没更新了,没有坚持下来!希望我能keep on. 最近一个月是考试月,可能更新会比较少.
- 个人作业week3——代码复审
1. 软件工程师的成长 感想 看了这么多博客,收获颇丰.一方面是对大牛们的计算机之路有了一定的了解,另一方面还是态度最重要,或者说用不用功最重要.这些博客里好些都是九几年或者零几年就开始学习编 ...
- 看看C# 6.0中那些语法糖都干了些什么(终结篇)
终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...
- Atitit. 项目文档目录大纲 总集合 v2
Atitit. 项目文档目录大纲 总集合 v2 -----Atitti.原有项目源码的架构,框架,配置与环境说明 v3 q511 -----Atitit.开发环境 与 工具 以及技术框架 以及 注意 ...