====== 类型兼容性(Type Compatibility) ====== 两个类型兼容(compatible),是指两个类型是同一个类型,或者“足够相近”可当作同一类型看待。由于typedef并没有引入新的类型,所以不影响兼容性的判断。 具体规则如下: ===== 算术类型(Arithmetic) ===== 两个算术类型兼容的唯一条件是他们为同一个类型。例如short与short int兼容,但与int、long不兼容。 需要特别注意的是,char、signed char、unsigned char都是不同的类型,因此也不兼容。 此外,类型限定符(type qualifiers)会改变类型,所以const int与int是不同的类型。 ===== 枚举类型(Enumeration) ===== 枚举类型与具体实现对应的整数类型(integer)相兼容。每个枚举类型的定义都产生一个新类型,所以没有两个枚举类型是兼容的。 例如: enum E1 {a, b} e1; enum E2 {c, d} e2; 这里e1与e2的类型是不兼容的。 不过,由于枚举通常被当作整数处理,所以,不同的枚举类型无论兼容与否,也可混合使用。 ===== 数组类型(Array) ===== 两个数组类型要兼容,首先它们的元素类型要兼容;其次,如果它们的长度都是固定的,则长度必须相等。 例如: extern int a[]; int b[5]; int c[10]; const int d[10]; int e[n]; 其中: - a与b、c、e都兼容; - b与a、e兼容; - c与a、e兼容; - e与a、b、c兼容; - d与其他变量都不兼容。 从这些例子可以看到,兼容性不能传递。 ===== 指针类型(Pointer) ===== 两个指针类型要兼容,首先它们的类型限定符要相似,其次,它们指向的类型要兼容。 ===== 函数类型(Function) ===== 两个函数类型要兼容,首先它们的返回值类型要兼容;其次: - 如果他们都有原型(prototype),则参数个数和变参(%%...%%)的使用必须一直,且每个参数的类型必须兼容; - 如果只有一个函数有原型,则原型的参数列表中不能含变参(%%...%%),并且每个参数的类型必须与该类型按[[.:function_argument_conversions|函数参数转换]]提升后的类型兼容。 ===== 结构体/联合类型(Struct/Union) ===== 每个结构体/联合类型的定义都产生一个新类型,所以没有两个结构体/联合类型是兼容的。 例如: struct { int a; int b; } x; struct { int a; int b; } y; struct s { int a; int b; } u; struct s v; typedef struct s TS; TS w; 这里x、y、u的类型都是不同的,但u、v、w的类型相同。 {{tag>C语言}}