这里仅讨论数组函数相关的复杂类型。

一、数组类型

如果有数组对象定义:

int a[10];

那么这个定义也隐式定义了一种数组类型

int [10]

数组对象a的类型就是这个;数组对象a的基类型是int

数组的类型由三个维度衡量:

  • 维数
  • 每一维的长度
  • 基类型

如果说,两个数组对象的类型相同,那么就说明二者在上述三个维度上都是一样的。例如,如果再有:

int b[10];
int c[5];
float f[10];
int a2[10][10];

那么:

  • b的类型与a的一样。
  • c的类型与a的不一样。二者维数、基类型相同,但长度不同。
  • f的类型与a的不一样。二者维数、长度相同,但基类型不同。
  • a2的类型与a的不一样。二者基类型、第一维长度相同,但维数不同。

C/C++一个令人烦恼的语法是:数组对象名会将类型名分割成两部分,从而造成认读上的困难。个人认为,如果哪天C标准将这种语法改为:int[10] a; 可能更好一点。

二、函数类型

如果有函数签名:

int f(int i);

那么这个签名也隐式定义了一种函数类型

int (int)

函数f的类型就是这个。

函数的类型由三个维度衡量:

  • 参数个数
  • 每一个参数的类型
  • 返回值类型

函数类型中必须有参数的类型,但不需要参数的名字!

如果说,两个函数对象的类型相同,那么就说明二者在上述三个维度上都是一样的。例如,如果再有:

int g(int i);
int h(float); //函数声明可以不要参数的名字
float k(int i);
int m(int i, int j);

那么:

  • g的类型与f的一样。
  • h的类型与f的不一样。二者参数个数、返回值类型相同,但参数类型不同。
  • k的类型与f的不一样。二者参数个数和类型相同,但返回值类型不同。
  • m的类型与f的不一样。二者参数类型、返回值类型相同,但参数个数不同。

三、函数指针类型

如果有这样的定义:

int (*pf)(int i);

那么这个定义也隐式定义了一种指向函数的指针类型,简称函数指针类型

int (*)(int)

函数指针pf的基类型是:

int (int)

这是指针对象pf的基类型,说明了pf指向了一个函数,该函数具有这样的特征:

  • 有一个参数
  • 这个参数的类型是int
  • 函数的返回值类型是int 基于此(同时承前例),指针pf能指向函数g
    pf = g; //注意:只是函数名g,后面没有()!否则就要调用g了,pf得到的是返回值!
    pf(2); //或者:(*pf)(2);  都是在调用函数g()