有很多关于如何读取typedef的教程,特别是对于函数指针。左右规则始终以&#34开头;找到新定义的类型,然后......"。我理解"然后......"部分,但不是如何找到新类型。
我知道这是"直觉",但我希望有一个计算机可以理解的明确配方。
我的第一个想法:新类型是您遇到的第一种尚未定义的类型。对于函数指针为True:
typedef char (*(*x[3])(int y))[5];
这里,x是第一个未定义的标识符,因此x是新类型。现在,看看这个:
typedef struct { int y; } x;
typedef union { int y; } x;
typedef enum { y } x;
此规则不适用:y是第一个未知标识符,但x是typedefed类型。
是否有规则在所有可能的typedef中找到新的typedefed类型?
答案 0 :(得分:0)
好吧,你的y实际是定义的:在前两个例子中, y 是匿名struct / union中int类型的成员变量,因此定义良好。在第三个示例中, y 是枚举成员之一,并且再次定义良好。为了更好地理解,想象一下你的typedef会写成:
struct _x { int y; };
typedef struct _x x;
union _x { int y; }
typedef union _x x;
enum _x { y };
typedef enum _x x;
(C ++允许在所有三种情况下将其简化为typedef _x x;
,但C不然,但是......)
从typedef的角度来看,它完全相同。唯一真正的区别是现在typedef类型有名称(_x)......
答案 1 :(得分:0)
每种类型都存在非指针类型,后跟零个或多个限定符,其中限定符可以是*,&,const,volatile和/或restrict。在这些限定符之后,新的typename出现在typedef中。这会将问题更改为'这些限定符出现在哪里' 因为它们并不真正出现在组成基本类型的角色的末尾,但可以出现在中间的某个地方。当基类型是数组和/或(成员)函数时。
例如:
typedef int array[5]; // new type 'array' of type int[5].
typedef int* array[5]; // new type 'array' of type int*[5];
typedef int (*array)[5]; // new type 'array' of type pointer-to-int[5].
typedef int function(float); // new type 'function' of type int ()(float)
typedef int (*function)(float); // new type 'function' of type int (*)(float) or pointer-to int ()(float).
typedef int (Class::*member)(float); // new type 'member' of type member-function-pointer to int (Class::)(float).
这些是限定符出现在中间的唯一类型,其余的格式为:
typedef SOMETYPE<qualifiers here> newtype_here;
如果它们也可以组合在一起,那么这些结构仍然很容易解析。又名:
数组:
TYPE name [DIM]
函数指针:
RETTYPE (*name) (PARAMS)
一组函数指针:
RETTYPE (*name[DIM]) (PARAMS)
返回指向数组的指针的函数:
TYPE (*name(PARAMS)) [DIM]
指向函数的指针(1)返回对const函数(2)指针数组的引用:
RETTYPE (* const (&(*name)(PARAMS2))[DIM])(PARAMS1)
所以,如果你可以消除PARAMS的所有括号,这些括号可以通过它们以已知类型(即:(int ...))开头的事实来识别,那么新类型将一直出现在在一个或多个限定符之后,在最内部的一对括号内(或不是起作用的(PARAMS))。
让我们按步骤构建上面的类型:
指向 - 函数(2)返回 - 参考 - 一个数组 - 一个常数 - 指向 - 函数(1)
现在向后阅读:
函数(1):
RETTYPE ( )(PARAMS1)
^
指向:
RETYPE (* )(PARAMS1)
^
(是)const:
RETTYPE (* const )(PARAMS1)
^
一个数组:
RETTYPE (* const ( )[DIM])(PARAMS1)
^
参考:
RETTYPE (* const (& )[DIM])(PARAMS1)
^
函数(2)返回:
RETTYPE (* const (& ( )(PARAMS2))[DIM])(PARAMS1)
^
指向:
的指针RETTYPE (* const (& (* )(PARAMS2))[DIM])(PARAMS1)
^
然后新的类型名称将放在^指向的位置。