C语言陷阱——类型转换

 以下例子取自《深入理解计算机系统》。

 考虑如下的C语言代码:

 1 #include<stdio.h>
 2
 3 typedef unsigned char* byte_pointer;
 4
 5 void show_bytes(byte_pointer pointer, int size){
 6     int i = 0;
 7     for (i = 0; i < size; ++i){
 8         printf("%.2x", pointer[i]);
 9     }
10 }
11
12 int main(){
13     short sx = -12345;
14     unsigned uy = sx;
15     printf("uy = %u:\t", uy);
16     show_bytes((byte_pointer)&uy, sizeof(unsigned));
17     printf("\n");
18 }

该程序在小端法的机器上会产生如下输出:uy = 4294954951:        c7cfffff

这表明当把short转换成unsigned 时,我们先改变大小,之后在完成从有符号到无符号的转换。也就是说(unsigned)sx等价于(unsigned)(int)sx,求值得到4294954951,而不等价于(unsigned)(unsigned short)sx,后者求值得到53191。事实上,这个规则是C语言标准要求的。

另外,当执行一个运算时,如果它的一个运算数是有符号的而另一个是无符号的,那么C语言会隐式地将有符号参数强制类型转换为无符号参数,并假设这两个数都是非负的,来执行这个运算。这种方法对于标准的算数运算并无多大差异,但是对于<和>这样的关系运算符来说,它会导致非直观的结果。

例如对(-1 < 0U)这个表达式求值,其结果为0。因为第二个运算数是无符号的,第一个运算数会被隐式地转换为无符号数,因此表达式就等价为(4294967295U < 0U),这个答案显然是错的。

基于同样的理由,我们考虑一下代码:

1 double sum_elements(double a[], unsigned length){
2     int i;
3     double result = 0;
4     for (i = 0; i <= length - 1; ++i){
5         result += a[i];
6     }
7     return result;
8 }

当传入的length=0时,会产生越界错误。

时间: 2024-08-04 09:57:32

C语言陷阱——类型转换的相关文章

c 语言里 类型转换那些事儿

一: 起因 (1)最近接触了类型转换,例如有符号数转化为无符号数 ---- int 转化为 unsigned int类型,莫要想当然的转化: (2)弥补一下自己当初学习计算机组成原理时,原码.反码.补码就比较容易混淆的概念: (3)double类型的如何判断某一个参数是否为零,直接 == 0.0,,貌似可以 ---- 确实有时可以,但是有时却不可以,这是为什么? (4)知识补充:在int 有符号数中:0x80000000 (除了符号位为1,其余全部为零) ---- 最小的数(-214748364

C语言自动类型转换

自动转换遵循以下规则: 1) 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 2) 转换按数据长度增加的方向进行,以保证精度不降低.(eg:int型和long型运算时,先把int量转成long型后再进行运算.) a.若两种类型的字节数不同,转换成字节数高的类型 b.若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型 3) 所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算. 4) char型和short型参

C语言数据类型转换

变量的数据类型是可以转换的.转换的方法有两种,一种是自动转换,一种是强制转换. 自动转换 自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成.自动转换遵循以下规则: 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 转换按数据长度增加的方向进行,以保证精度不降低.如int型和long型运算时,先把int量转成long型后再进行运算. 所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算. char型和short型参与运

C语言数据类型转换基本规则

     程序语句和表达式通常应该只使用一种类型的变量和常量,但是如果混合使用类型, C使用一个规则集合来完成数据类型的自动转换. 以下是一些C数据类型转换的基本规则: 1.当出现在表达式中时,有符号和无符号的char和short类型都将自动转换为int. 2.在包含两种数据类型的任何运算中,较低级别类型将会转为运算中另一个较高级别的数据类型. 3.数据类型级别从高到低的顺序是long double.double.float.usigned long long.long long unsigne

JAVA语言基础——类型转换

1.自动类型转换 自动类型转换又称作隐式转换,可以将一个int变量转换为float类型. 1 public class Conver { 2 public static void main(String[] args) { 3 4 byte mybyte = 127; 5 int myint = 150; 6 float myfloat = 452.12f; 7 char mychar = 10; 8 double mydouble = 45.46546; 9 System.out.printl

一步一步学习C#语言【类型转换】

类型转换的概念 所有的数据在计算机内存中都是由一系列的位组成,即0和1组成.不同的类型用不同的位模式来存储. 类型转换即是一系列位从一种类型的变量到另一种类型的变量中,它们占用的存储空间可能不相同,目标类型可能能存储下所有源数据,结果可能会得到不期望值. 类型转换有两种形式:隐式转换和显式转换. 隐式转换 隐式转换不需要做任何动作,也不需要编写任何代码来实现. 即使两个变量存储信息完全相同,使用不同类型来解释他们时,方式也是不同的. 简单类型只有bool类型和string类型没有隐式转换. 隐式

c语言强制类型转换

一.强制类型转换 printf("3/2+100.5=%f",3/2+100.5);//100.5错误表达 printf ("    (float)3/(float)2 +100.5f=%f \n",    (float)3/(float)2 +100.5f); // (float) 前缀 二.自动类型转换和隐式类型转换 例1: printf ("    3/2+100.5=%f \n",       (float)3/2 +100.5f); p

go语言:类型转换

类型转换用于将一种类型的变量转换为另一种类型的变量. 有以下场景: package main import "fmt" func main() { var sum int = 17 var count int = 5 mean := sum / count fmt.Printf("mean 的值为: %f\n", mean) } 输出:mean 的值为: %!f(int=3) 上面的代码中,变量sum和count都为整数,通过对两个变量作除法,因为不能整除,所以应该

C语言强制类型转换和浮点数带来的问题

强制类型转换: (int)(6.9)的结果就是6 1/(float)(sum)的结果是浮点数 浮点数带来的问题 float i=6.25,实际上计算机很可能把i存为6.249999.. 用浮点型存放小数,实际存放的是该小数的近似值 存放5.5,实际存放的是5.499999 有一个浮点型变量x,如何判断x的值是否为0 因为0.0000001也可能被存成是0,拿这个数和0.000000000000000000000000001比较,如果较小,那么就是0了 for(i=5.25;i<6.25;i++)