C语言陷阱——类型转换
以下例子取自《深入理解计算机系统》。
考虑如下的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语言陷阱——类型转换的更多相关文章
- 详解C语言的类型转换
1.自动类型转换 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围是0-255( ...
- C语言进阶——类型转换04
C语言内可以进行类型转换: 强制类型转换 隐式类型转换 强制类型转换的语法: (tpye)value (type)value_name 强制类型转换的结果: 目标类型可以容纳目标值:结果不变 目标值不 ...
- C#语言 数据类型 类型转换
数据类型有 基本数据类型 和 引用数据类型 两大类型. 数据类型 C#语言 .NET(通用语言) 大小(字节) 值区间 基本数据类型 值类型 整型 不能存在小数点,可以有负数 byte Byte ...
- c语言中类型转换与赋值运算符、算术运算符、关系运算符、逻辑运算符。原码、反码、补码。小解。
类型转换 自动转换 小范围的类型能够自动转换成大范围的类型.short->int->long->float->double 强制类型转换 (类型名)变量或数值 #include ...
- c语言强制类型转换
一.强制类型转换 printf("3/2+100.5=%f",3/2+100.5);//100.5错误表达 printf (" (float)3/(float)2 ...
- JAVA语言基础——类型转换
1.自动类型转换 自动类型转换又称作隐式转换,可以将一个int变量转换为float类型. public class Conver { public static void main(String[] ...
- C语言自动类型转换
自动转换遵循以下规则: 1) 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 2) 转换按数据长度增加的方向进行,以保证精度不降低.(eg:int型和long型运算时,先把int量转成lo ...
- C语言数据类型转换
变量的数据类型是可以转换的.转换的方法有两种,一种是自动转换,一种是强制转换. 自动转换 自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成.自动转换遵循以下规则: 若参与运算量的类型不同, ...
- C语言陷阱:浮点运算
在Stack overflow上看到这样一个问题. 计算如下表达式的值: P=(1/2-3/4)*(5/6-7/8)*…*[n/(n-1) - (n+2)/(n+3)]. 程序如下: #include ...
随机推荐
- Eclipse(Myeclipse)安装GoogleGWT
1,下载gpe http://code.google.com/p/googleappengine/并安装. 2,下载gwt http://code.google.com/intl/zh-CN/webt ...
- 刚才建立一个 swift 中文讨论社区,欢迎大家參与讨论
http://www.chinaswift.me 主要目的是收集 swift学习资源
- crontab 定时任务 每过多少分钟执行
被下面的问题纠结了一会 记录一下以备提醒 每过5分钟执行 */ * * * * curl localhost/system/dns/dnns.php?ac=ToDNS 每小时的第五分钟执行 0 * * ...
- [转] 用管道获得shell 命令的输出
用管道: 通过fgets(buf, n, ptr)buf就可以得到命令“ps -ef"一样的信息, 读帮助”man popen": char *cmd = "ps -ef ...
- CentOS 6.7编译安装MySQL 5.6
1.安装前准备 yum install make gcc gcc-c++ ncurses-devel perl bison-devel yum groupinstall "Developme ...
- 含有GROUP BY子句的查询中如何显示COUNT()为0的成果(分享)
在SQL Server数据库查询中,为了对查询成果进行对比.解析,我们经常会用到GROUP BY子句以及COUNT()函数来对查询成果进行分类.统计等.然则我们在应用的过程中往往会存在一些题目,本文我 ...
- node里如何查看浏览器信息
'use strict'; let http = require(`http`); http.createServer((req, res) => { console.log(req.heade ...
- WPF RichTextBox滚动条自动滚动实例、文本自动滚动实例
说明:1.后台代码添加测试 数据 2.使用 richTextBox.ScrollToVerticalOffset()方法,滚动竖直方向滚动条位置 3.使用定时器DispatcherTimer,修改页面 ...
- TFS 服务器更换后工作区无法绑定
需要删除工作区,删除命令如下 tf workspace /delete 工作区名;创建的用户 /server:TFS服务器 例 tf workspace /delete WHQ-PC;whq /ser ...
- Android -- 双击退出
实现android双击后退键退出当前APP功能 实现该功能基本思路是, 1, 监听后退键 , 比较两次后退间隔 , 低于两秒则出发退出 2, 退出当前APP 我选择在基类中BaseActivity 中 ...