在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
首先可以肯定的是,我们不能这样去理解,因为虽然我们按照这样的理解方式去理解对于上面这种形式(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型,而是比较复杂的类型,那该如何定义呢?事实上数组指针这种东西就已经够稀有的了,一般编程绝对不会用到,我们只需要能读懂一些比较复杂的东西就行了,自己没有必要构造这么复杂的类型。
比较复杂的表达式: 1、int (*(*(*p())[])())[]; 首先,根据p()判断p是一个函数,再根据p()前面的*号判断该函数返回一个指针,下面就看这个指针指向的是什么类型了,我们可以把*p()替换成一个*pointer,这个pointer就是函数p返回的指针,那么就成了int (*(*(*pointer)[])())[];再根据(*pointer)[],这说明了指针pointer是指向的一个数组,那么这个数组中的元素是什么类型呢?由于数组名实际上就是个指针,我们把(*pointer)[](即(*p())[])替换成一个array,这样就成了 int (*(*array)())[];发现array是一个函数指针,从而数组中的每个元素是函数指针,而这个函数呢,又返回一个指针类型,把(*array)()用func代替,就成了int (*func)[];这说明了func函数返回的是指向数组的指针,数组中的元素是int型。 这个表达式够酷!!!
2、p = (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
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论