C语言学习第十五天
2.7 类型转换
当一个运算符的几个操作 数类型不同时,就需要通过一些规则把它们转换为某种共同的类型。一般来说,自动转换时指把“比较窄的”操作数转换为“比较宽的”操作数,并且 不丢失信息的转换。针对可能导致信息 丢失的表达式,编译器可能会给出警告信息,比如把教长的整型值赋给较短的整型变量,把浮点型值赋值给整型变量,等等,但这些表达式并不非法。
由于char类型就是较小的整型,因此 在算术表达式中可以自由使用char类型的变量,比如下面的函数atoi就是将一串数字转换为相应的数值:
/* atoi 函数:将字符串s转换为相应的整型数 */
int atoi(char s[]) {
int i, n;
n = 0;
for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
n = 10 * n + (s[i] - '0');
return n;
}
函数lower是将char类型转换为int类型的另一个例子,它将ASCII字符集中的字符映射到对应的小写字母。如果待转换的字符不是大写字母,lower函数将返回字符本身。
/* lower函数: 把字符c转换为小写形式;只对ASCII字符集有效 */
int lower(int c) {
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}
上述这个函数是为ASCII字符集设计的。在ASCII字符集中,大写字母与对应的小写字母作为数字值来说具有固定的间隔,并且每个字母表都是连续的——也就是说,在A~Z之间只有字母。
标准头文件<ctype.h>定义了tolower(c)函数将c转换为小写形式,类似的,测试语句:
c >= '0' && c <= '9'
可以用该标准库中的函数
isdigit(c)
替代。
当关系表达式(如i>j)以及由&&、||连接的逻辑表达式的判定结果为真时,表达式的值为1;当判定结果为假时,表达式的值为0。因此,对于赋值语句
d = c >= '0' && c <= '9'
来说,当c为数字时,d的值为1,否则d的值为0。但是,某些函数(比如isdigit)在结果为真时可能返回任意的非0值。在if、while、for等语句的测试部分中,“真”就意味着“非0”,这二者之间没有区别。
C语言中,很多情况下会进行隐式的算术类型转换。一般来说,如果二元运算符(具有两个操作数的算术运算符称为二元运算符,比如+或*)的两个操作数具有不同的类型,那么在进行运算之前先要把“较低”的类型提升为“较高”的类型。运算结果为较高的类型。由如下规则:
如果其中一个操作数的类型为long double,则将另一个操作数转换为long double类型;
如果其中一个操作数的类型为double,则将另一个操作数转换为double类型;
如果其中一个操作数类型为float,则将另一个操作数转换为float类型;
将char与short类型的操作数转换为int类型;
如果其中一个操作数的类型为long,则将另一个操作数也转换为long类型。
一般来说,数学函数使用双精度类型的变量。使用float类型主要时为了在使用较大的数组时节省存储空间,有时也为了节省机器执行时间(双精度算术运算特别费时)。
赋值时也要进行类型转换。赋值运算符右边的值需要转换为左边变量的类型,左边变量的类型即表达式结果的类型。
当把较长的整数转换为较短的整数或char类型时,超出的高位部分将被丢弃。因此,下列程序段:
int i;
char c;
i = c;
c = i;
执行后,c的值将保持不变。无论是否进行符号扩展,该结论都成立。但是,如果把两个赋值语句的次序颠倒一下,则执行后可能会丢失信息。
如果x时float类型,i是int类型,那么语句x=i与i=x在执行是都要进行类型转换。当把float类型转换为int类型时,小数部分将被截取掉;当把double类型转换为float类型时,时进行四舍五入还是截取取决于具体的实现。
在任何表达式中都可以使用一个称为强制类型转换的一元运算符强制进行显示类型转换。
(类型名)表达式
练习2-3 编写函数htoi(s), 把由十六进制数字组成的字符串(包含可选的前缀0x或0X)转换为与之等价的整型值。字符串中允许包含的数字包括:0~9、a~f以及A~F。
______________________________________________________________
int htoi(char s[]) {
int i, n;
i = n = 0;
if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
i = 2;
for(; s[i] >= '0' && s[i] <= '9' || s[i] >= 'a' && s[i] <= 'f' || s[i] >= 'A' && s[i] <= 'F'; ++i) {
if(s[i] >= '0' && s[i] <= '9')
n = 16 * n + (s[i] - '0');
else if (s[i] >= 'a' && s[i] <= 'f')
n = 16 * n + (s[i] - 'a' + 10) ;
else
n = 16 * n + (s[i] - 'A' + 10) ;
}
return n;
}
______________________________________________________________