首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 计算机考试 > 等级考试 > 复习指导 >

C++应用实例十一(2)

2008-12-15 
c++数据类型及复杂声明推演

  另外一个例子:
  表达式 意义
  char *(*(**foo [][8])())[]
  char *(*(**foo [][8])())[] foo 是 … char
  char *(*(**foo [][8])())[] foo 是 一个数组 … char
  char *(*(**foo [][8])())[] foo 是 一个数组且成员为 8维数组 … char
  char *(*(**foo [][8])())[] foo 是 一个数组且成员为 8维数组且成员为 指针且指向 … char
  char *(*(**foo [][8])())[] foo 是 一个数组且成员为 8维数组且成员为 指针且指向 指针且指向 … char
  char *(*(**foo [][8])())[] foo 是 一个数组且成员为 8维数组且成员为 指针且指向 指针且指向 函数且返回 … char
  char *(*(**foo [][8])())[] foo 是 一个数组且成员为 8维数组且成员为 指针且指向 指针且指向 函数且返回 指针且指向 … char
  char *(*(**foo [][8])())[] foo 是 一个数组且成员为 8维数组且成员为 指针且指向 指针且指向 函数且返回 指针且指向 数组 … char
  char *(*(**foo [][8])())[] foo 是 一个数组且成员为 8维数组且成员为 指针且指向 指针且指向 函数且返回 指针且指向 数组且成员为 指针且指向 char
  译注:
  我们也可以采用另外一种方法就是层层类型定义的方法来解读,不过是从外向内的.比如例子1:
  typedef double * pDouble;
  typedef pDouble* ppDouble;
  typedef ppDouble a8ppDouble[8];
  a8ppDouble d;
  第二个例子:
  typedef char * pchar;
  typedef pchar apchar[];
  typedef apchar * papchar;
  typedef papchar fpapchar();
  typedef papchar (*pfpapchar)();
  typedef pfpapchar * ppfpapchar;
  typedef ppfpapchar a8ppfpapchar[8];
  typedef a8ppfpapchar aa8ppfpapchar[];
  typedef aa8ppfpapchar foo;
  附文:
  下面是对Steve Friedl的参考文章的部分译文,因为这里也同样的是解说这两个例子,不过对于规则上述说更详细。
  基本和派生类型
  基本类型就是上边提到的那些基本类型,这里还包括了struct,enum和union(译注:因为这个说明是针对c语言的,所以对于c++来说还要加上一个class类型)
  一个声明只能定义一种基本类型,并且它总是出现在声明式的最左边。基本类型可以被派生类型扩张或者说是修饰,并且c有三种派生类型:
  * 指针且指向(pointer to...)
  这里*表明这是一个指针,而且不言自明地它要指向某个东西
  [] 数组且成员为(array of...)
  数组可以是已定维数的--[10]--也可以是未定维数的--[],但是维数在我们理解声明具体含义的时候不是那么重要。典型地我们会把维数包含在声明里。这样可以明了的说“数组且成员为”某些东西。
  () 函数且返回(function returning...)
  函数通常是由一对圆括号来表明的--尽管可能在里面发现参数类型。参数列表其实在我们理解声明的时候是不重要的,可以忽略。应该注意到的是函数的括号和分组改变优先级的括号是不一样的:分组括号总是包围变量而函数括号却总是在变量名(即函数名)的右边。
  如果函数不返回值则它是无意义的(我们可以使用void来表示返回为空)。
  一个派生类型总是修饰一个基本变量或者另外一个派生变量。我们在理解声明的时候一定要包括介词(to,of,returning)。说“指针”而不是“指针且指向...”会导致你的声明分离。
  操作符的优先级
  几乎每一个c程序员都很熟悉操作符的优先级表。比如乘除的优先级要高于加减,但是括号可以改变这个优先级。这个对于通常的表达式很自然,但是这个规则也可以运用到声明语句中--它们是类型表达式而不是计算表达式。
  数组符号[]和函数符号()比指针*有更高的优先级,这样我们可以推导出一些规则(这个规则和上边所提的是一样的,这里不再啰嗦,离子的推衍也不再重复)。
  抽象声明
  C标准也支持抽象声明。它可以用在需要类型描述但是又不需要实际变量的情况下--cast,抛掷,和作为sizeof的参数。比如:
  int (*(*)())()
  对于上边的问题--从哪里开始,答案是找到一个变量名可以放得下的地方,然后把它当成一个通常的声明。只有一个地方可以放置这个变量名并且找到它也是直截了当的。遵循以下语法规则:
  - 在*的右边
  - 在[]的左边
  - 在函数操作符()的左边
  - 在分组括号()的内部
  由上面的例子我们可以看到有两个地方符合前三条规则:
  int (*(* • ) • ())()
  但是如果考虑则四条,则只有左边的位置符合了。
  int (*(*foo)())()
  它表示:
  foo是 指针且指向 函数且返回 指针且指向 函数且返回 int
  语义限制
  注意不是所有的派生组合都被允许的.这样就可能声明一个合乎语法却没有语义内涵的东西来:
  --不能有 数组且成员为函数
  使用 数组且成员为 指针且指向 函数且返回.... (译注:但是我们知道函数的地址就是函数本身,所以可以说 数组且成员为 函数指针且返回)
  --函数不能返回函数
  同样使用函数指针代替
  --函数不能返回数组
  可以使用 函数且返回 指针且指向 数组且成员为...(译注:同样地我们知道数组名同时也是数组首元素的地址,还是该数组的地址)
  --数组中只有最左的[]可以是未定义的
  --void是限制类型,它只有在和指针*以及函数()在一起时才有效.

 


3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.com/exam/

热点排行