typedef似乎很简单,如typedef int integer;然而,这些简单的typedef语句容易让人产生一种误解,typedef就是一种宏替换,把后面的自定义类型替换成前面的已知类型,事实是这样的吗?显然不是!

首先可以肯定的是,我们不能这样去理解,因为虽然我们按照这样的理解方式去理解对于上面这种形式(typedef int integer)可以通过,但是对于其它方式是通不过的。

考虑这样的问题:如何定义一个指向整型的指针类型?如何定义一个函数指针类型?

第一个问题很简单:typedef int* int_pointer;即可,对于第二个问题,似乎就没有那么简单了,首先,看函数指针的定义方法:int (*p)(const&, int); 这个p指向的函数必须返回int,形参必须是const&和int。现在要将这种指针类型命名为func_pointer,其定义的方法如下:

typedef int (*func_pointer)(const&, int);

按照以下方式理解就是正确的了:typedef int integer;将typedef去掉,那就是个变量的定义,这儿即定义了一个int型的变量integer,考虑这个integer是什么类型的,那么这个typedef语句就是将integer定义为这个类型的。将typedef int (*func_pointer)(const&, int);中的typedef去掉,就成了一个函数指针定义,即func_pointer被定义为函数指针类型变量,那么原来的typedef即将func_pointer定义为函数指针类型。

int (*testCases[10])();

这个表达式是什么意思?指针,数组,函数糅合在了一起问题变得复杂起来。它定义了数组,testCases[10],数组中的元素是函数指针,函数指针的类型是 int (*)();

怎么来理解这种定义呢?首先考虑数组的定义,数组的定义一般模式是:类型 数组名[大小];

考虑这个表达式,似乎是定义了一个数组,但是数组名[大小]被夹在了中间,那么类型是什么呢,发现类型并不是简单的数据类型,而是一个函数指针类型int (*p)(),这个函数没有参数,返回int型。从而这个表达式的含义是:定义了一个函数指针型的数组,大小是10。可以利用typedef来简化这种定义:

typedef int (*PFV)();

PFV testCases[10];

其实int (*testCases[10])();这儿我们定义了一个函数指针数组,数组是主体。

下面考虑这样的问题:如何定义一个指向数组的指针?

指向数组的指针,好像比较新鲜,所谓指向数组的指针,即指针的一步跨越是一个数组,跟指向整型的指针一步跨越一个整型一个道理。事实上前面已经碰到了指向数组的指针,如二维数组名,实际上就是一个指向数组的指针,它一次跨越一行的数据,实际上即是跨越了一个一维数组,而三维数组名呢,也是一个指向数组的指针,它一次跨越的是低维组成的一个二维数组。

数组指针(即指向数组的指针)的定义: int (*ptr)[3];

这个表达式定义了一个数组指针ptr,ptr一次跨越一个由3个int型组成的一维数组。发现其定义的方式与函数指针定义的方式很相似,只是把()换作了[]。更进一步,如果要定义一个指向数组的指针,而数组中的元素不是简单的int型,而是比较复杂的类型,那该如何定义呢?事实上数组指针这种东西就已经够稀有的了,一般编程绝对不会用到,我们只需要能读懂一些比较复杂的东西就行了,自己没有必要构造这么复杂的类型。

比较复杂的表达式:

1int (*(*(*p())[])())[];

首先,根据p()判断p是一个函数,再根据p()前面的*号判断该函数返回一个指针,下面就看这个指针指向的是什么类型了,我们可以把*p()替换成一个*pointer,这个pointer就是函数p返回的指针,那么就成了int (*(*(*pointer)[])())[];再根据(*pointer)[],这说明了指针pointer是指向的一个数组,那么这个数组中的元素是什么类型呢?由于数组名实际上就是个指针,我们把(*pointer)[](即(*p())[])替换成一个array,这样就成了 int (*(*array)())[];发现array是一个函数指针,从而数组中的每个元素是函数指针,而这个函数呢,又返回一个指针类型,把(*array)()用func代替,就成了int (*func)[];这说明了func函数返回的是指向数组的指针,数组中的元素是int型。

这个表达式够酷!!!

2p = (int( * (*)[20])[10])q;

这是一个强制类型转换,q被强制类型转换成一个这样的指针类型,这个指针呢直线一个具有20个元素的数组,这个数组中的元素也是指针,是指向另外一种数组,这种数组是含有10个int型数据的一维数组。

可见,分析复杂的表达式时(所谓复杂,即糅合了指针,数组,函数三样,缺少了一样就不会复杂了),从括号的最里层做起,最里层的东西是复杂表达式的“根节点”,然后一层一层脱,脱的时候,是这样的,比如里层是个数组,那么就是说这个数组的元素是什么呢,那就是外层的东西,如果里层是个有返回值的函数,那么就是说这个函数返回什么值呢?那就是外层的东西,就这样一层一层地把表达式解析清楚。

关于typedef还有一些要说的:

typedef  int (*PFV)(); 这是定义了一个函数指针,那么PFV p;就可以定义了一个指向函数的指针。

typedef int (*p[10])(); 这是把p定义为函数指针数组,那么 p array;语句就可以定义了一个函数指针数组,数组名即为array,array这个数组含10个元素。

typedef int (*parray)[3];这是定义了一个指向整型数组的指针,那么 parray ptr;就定义了一个指向数组的指针。如何对这个ptr赋值或者初始化呢?事实上,是通过二维数组名来对其进行赋值(初始化)的,因为二维数组名作为指针来讲,就是一个指向数组的指针,一次跨越一个数组。

typedef int a[3][3]; 这个语句什么意思呢?这是把a定义为一个3*3的整型数组类型。当a b = {1}时就完成了一个3×3的整型数组的定义初始化的工作。

同样,简单一点 typedef int a[3];这个语句是把a定义为一个一维数组类型。

typedef  void func(int); 这个语句定义了一个函数类型。通过这个typedef,我们可以比较清晰地定义出函数指针,func* p;即可。

typedef char* string;

const string str;

这个str是什么类型的呢?const char * str,即指向常量的指针类型?事实上,答案有些不可思议,str是一个常量指针,而不是指针常量,即const修饰符针对的是指针,而不是char

转载于:https://www.cnblogs.com/krisdy/archive/2009/06/15/1503689.html

[C++ rudiment][转]typedef 使用相关推荐

  1. C++ 笔记(04)— 数据类型(各类型占用内存 sizeof、typedef 声明)

    编程语言中变量保存的是它所存储值的内存位置.也就是说在创建一个变量时,就会在内存中开辟一些空间.操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么. 1. 基本数据类型 类型 关键字 ...

  2. rb c语言,C语言,RB和RBT什么区别啊???这里的typedef 什么作用???

    满意答案 guiyalm4704 2017.01.10 采纳率:58%    等级:12 已帮助:5026人 1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是 ...

  3. C语言小知识:typedef\函数模板\

    (1)typedef用法: typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等).在编程中使用t ...

  4. Typedef用法(转载)

    在C的学习过程中,现在才发现,以前有那么多被忽略的重点:现在是慢慢拾起这些重点的时候,通过百度和博客,我感觉我学到了很多东西,自己只是在别人说的基础上,按照自己学习的过程在这里记录一下,以后有时间回过 ...

  5. C++中typedef和define的区别

    typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: ...

  6. typedef和define具体的详细区别

    1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错.例如: #define PI 3.141 ...

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

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

  8. C++/C++11中用于定义类型别名的两种方法:typedef和using

    类型别名(type alias)是一个名字,它是某种类型的同义词.使用类型别名有很多好处,它让复杂的类型名字变得简单明了.易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的.在C++中,任何 ...

  9. C++之typedef 小记

    2019独角兽企业重金招聘Python工程师标准>>>  以前曾不知道为何要用typedef,随着开发的深入,真正感受到了其内涵所在: 1.如:typedef int DataT ...

最新文章

  1. 深度学习之Pytorch基础教程!
  2. Navicat Mac 虚拟组和连接颜色的作用
  3. 查看suse系统版本
  4. UVA11078开放式学分制(前面-后面的最大值)
  5. bash: make: command not found - 解决办法
  6. 计算机二级证书如何考取,计算机二级证书怎么领 考试成绩怎么算
  7. 专家票选! 2020 年度 10 篇人工智能经典论文(1-5)
  8. 第十届 蓝桥杯样题 ——结果填空
  9. Exception in thread main java.time.format.DateTimeParseException: Text '31-Dec-13' could not be pa
  10. 【jzoj】2018.2.7NOIP普及组——某【BC】组模拟赛
  11. 如何实现用户通信授权的可信、可知、可追溯?——通信授权服务技术解读
  12. java swing 按键_Java Swing 快捷键
  13. Linux内核调度——《奔跑吧Linux内核》学习笔记
  14. windows防火墙设置_合理利用Windows 7防火墙,阻止部分功能,避免网络恶意软件攻击...
  15. 基于opencv的身份证识别系统
  16. 硬盘的IDE、AHCI和NVMe模式区别
  17. 洛谷 P3987 我永远喜欢珂朵莉~(Splay+BIT+无限卡常)
  18. 粘贴时word左下角出现“正在与服务器联系以获取信息,按ESC取消”
  19. 追忆那似水流年的产品梦
  20. iApp裕v3语言认识us与ug

热门文章

  1. C语言面试-指针和引用的使用场景?
  2. mysql 1308_Mysql恢复数据报ERROR 1308 : LEAVE with no matching label_MySQL
  3. layui 分页 固定底部_论layui的使用体验
  4. java 区号_求您!JAVA作业,窗口查询区号!
  5. JAVA听力源码,英语听力练习
  6. 如何选配合适的百兆或者千兆工业交换机
  7. 【渝粤教育】 广东开放大学 21秋期末考试婚姻家庭法10218k2
  8. layui datetimepicker 只日期范围到当前时间的前一天_浪琴手表如何正确调整日期?手表调日期的方法...
  9. python qtdesigner安装,PyCharm+Qt Designer+PyUIC安装配置教程详解
  10. java架构师_成为一名Java高级架构师究竟要学哪些东西??