类型转换
当操作符的操作数类型不一致时会发生类型转换,这被称为“寻常算术转换”,它负责把两个不同的操作数类型转换成同一种普通类型,转换后的类型一般也就是结果类型
C语言中的类型转换比一般人想象中的要广泛的多,再涉及类型小于int或double的表达式中,都有可能出现类型转换,举个栗子:
printf("size=%d\n",sizeof'A');
这行代码打印出存储一个字符字面值类型的长度,但是事实上的结果为4(或者是你机器上int的长度),根据提升规则,它由char提升为int,这个概念在K&R C中讲的过于简单了,它在39页是这样描述的:
- 在表达式中,每个char都被转换为int…注意所有位于表达式中的float都被转换为double…由于函数参数也是一个表达式,所以当参数传递给函数时也会发生类型转换,具体的说,char和short转换为int,而float转换为double
这个特性被称为类型提升,当它发生于整型类型提升时称为“整形提升”,ANSI C延续了自动类型提升的概念,尽管在许多地方它已褪色,关于类型提升,ANSI C标准有如下说明:
char c1,c2;
/*...*/
char c1=c1+c2;
“整型提升”规则要求抽象机器把每个变量的值提升为int的长度,然后对两个int值执行加法运算,然后再对运算结果进行剪裁,如果两个char的加法运算结果不会发生溢出异常,那么实际执行时只需要产生char类型的运算结果,可以省略类型提升
类似,在下面栗子中
float f1,f2;
double d;
/*...*/
f1=f2*d;
如果编译器可以确定用float进行运算的结果跟转换为double的运算结果一样,那么也可以使用float来进行乘法运算
整型提升就是char、short int和位段类型以及枚举类型将被提升为int,前提是int能够完整的容纳原先的数据,否则将被转换为unsigned int,ANSI C表示如果编译器能够保证运算结果一致,也可以省略类型提升,这通常出现在表达式中存在常量的情况
函数原型
建立原型就是为了消除一种普通但很难发现的错误,就是形参和实参之间类型不匹配
在K&R C中如果向函数传递一个短于int的整数,函数实际所接收到的是int,如果传递一个float,函数实际接收到的是double,在被调用函数的函数体内,这些值会根据函数定义时参数的声明类型自动剪裁为该类型
相反,如果使用了函数原型,缺省参数提升就不会发生,如果参数声明为char,则所传递的也是char,如果使用新风格的函数定义,编译器就会嘉定参数是准确声明的,于是便不进行类型提升,并据此产生代码
内容摘自《C专家编程》!!!