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

 考虑如下的C语言代码:

 #include<stdio.h>

 typedef unsigned char* byte_pointer;

 void show_bytes(byte_pointer pointer, int size){
int i = ;
for (i = ; i < size; ++i){
printf("%.2x", pointer[i]);
}
} int main(){
short sx = -;
unsigned uy = sx;
printf("uy = %u:\t", uy);
show_bytes((byte_pointer)&uy, sizeof(unsigned));
printf("\n");
}

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

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

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

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

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

 double sum_elements(double a[], unsigned length){
int i;
double result = ;
for (i = ; i <= length - ; ++i){
result += a[i];
}
return result;
}

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

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

  1. 详解C语言的类型转换

    1.自动类型转换 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0-255( ...

  2. C语言进阶——类型转换04

    C语言内可以进行类型转换: 强制类型转换 隐式类型转换 强制类型转换的语法: (tpye)value (type)value_name 强制类型转换的结果: 目标类型可以容纳目标值:结果不变 目标值不 ...

  3. C#语言 数据类型 类型转换

    数据类型有  基本数据类型 和  引用数据类型 两大类型. 数据类型 C#语言 .NET(通用语言) 大小(字节) 值区间 基本数据类型 值类型 整型 不能存在小数点,可以有负数 byte Byte ...

  4. c语言中类型转换与赋值运算符、算术运算符、关系运算符、逻辑运算符。原码、反码、补码。小解。

    类型转换 自动转换 小范围的类型能够自动转换成大范围的类型.short->int->long->float->double 强制类型转换 (类型名)变量或数值 #include ...

  5. c语言强制类型转换

    一.强制类型转换 printf("3/2+100.5=%f",3/2+100.5);//100.5错误表达 printf ("    (float)3/(float)2 ...

  6. JAVA语言基础——类型转换

    1.自动类型转换 自动类型转换又称作隐式转换,可以将一个int变量转换为float类型. public class Conver { public static void main(String[] ...

  7. C语言自动类型转换

    自动转换遵循以下规则: 1) 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 2) 转换按数据长度增加的方向进行,以保证精度不降低.(eg:int型和long型运算时,先把int量转成lo ...

  8. C语言数据类型转换

    变量的数据类型是可以转换的.转换的方法有两种,一种是自动转换,一种是强制转换. 自动转换 自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成.自动转换遵循以下规则: 若参与运算量的类型不同, ...

  9. C语言陷阱:浮点运算

    在Stack overflow上看到这样一个问题. 计算如下表达式的值: P=(1/2-3/4)*(5/6-7/8)*…*[n/(n-1) - (n+2)/(n+3)]. 程序如下: #include ...

随机推荐

  1. poj 1383 Labyrinth【迷宫bfs+树的直径】

    Labyrinth Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 4004   Accepted: 1504 Descrip ...

  2. Spring注入-Map

    在spring框架中为Map注入属性 1map映射的对象创建 package com; /** * Map集合在spring中的使用测试 */ public class User { private ...

  3. redis.config翻译

    # Redis configuration file example#redis配置文件范例 # Note on units: when memory size is needed, it is po ...

  4. [struts2学习笔记] 第一节 关于struts2的简单认知

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/40298287 官方文档:http://struts.apache.org/releas ...

  5. 遍历datatable的几种方法【转载】

    遍历datatable的方法2009-- :02方法一: DataTable dt = dataSet.Tables[]; ; i < dt.Rows.Count ; i++) { string ...

  6. nginx 笔记

    nginx 这个轻量级.高性能的 web server 主要可以干两件事情: 〉直接作为http server(代替apache,对PHP需要FastCGI处理器支持): 〉另外一个功能就是作为反向代 ...

  7. Building Tomcat7 source step by step---官方文档

    Table of Contents Introduction Download a Java Development Kit (JDK) version 6 Install Apache Ant 1. ...

  8. Apple-Watch开发1

    Communicating between the iOS app and the Watch Extension There are four scenarios where an app and ...

  9. iOS UIKit:viewController之定义(2)

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  10. 第一篇:python基础

    python基础   python基础 本节内容 python起源 python的发展史 为什么选择python3 第一个python程序 变量定义 表达式和运算符 用户输入 流程控制 判断 流程控制 ...