C语言细节——献给入门者(三)

>>主题:关于强制类型转换

  先来瞎扯下强制类型转换,c语言有很多数据类型,long,short,int,float,double,bool,char等等。当我们要将一种数据类型赋值给另一种数据类型,或者将某个操作数进行如此的转化的时候,就用到了强制类型转换。 

  强制类型转换分成两种:1.显示强制类型转换(主动)  2.隐式强制类型转换(被动/自动)

  要区分这两者很简单,看下面例子:(we assume that b is a variable of integer.)

char a = (char)b;

char a = b;

 所以区分两者只要看这个(char)是否显式的写出来。但我们要注意,这两个的区别绝对不是这么简单。让我们看下去...

》》》如果一个运算符两边的运算数类型不同,先要将其转换为相同的类型,即较低类型转换为较高类型,然后再参加运算,转换规则如下图所示。

这段和这图是我百度来的,他说计算机会主动把float,int分别转换成double,long计算,后来想来一下发现跟计算机组成学的不一样,况且如果都这样计算,那还需要小数据类型干嘛呢?计算机速度何必非得用双精度来测量?后来我自己测了一下,发现果然是瞎扯,我就不用这个图说啦~(附上测试代码)

  (ps:以下按照int为32位来说明):      

测试代码:

#include <stdio.h>
int main()
{
int a=,b=;
int c=a+b;
long aa=,cc=;
long bb=aa+cc; printf("%d\n",c );
printf("%ld\n",bb );
return ;
}

反汇编后所得(部分代码):

     movl    $, -(%rbp)
movl $, -(%rbp)
movl $, -(%rbp)
movl -(%rbp), %eax
addl -(%rbp), %eax
movl %eax, -(%rbp)
movq $, -(%rbp)
movq $, -(%rbp)
movq -(%rbp), %rcx
addq -(%rbp), %rcx
movq %rcx, -(%rbp)
movl -(%rbp), %esi
movb $, %al

感觉一下子打乱我思路了,让我捋一捋。。。

》》》先看下两个优先级的例子,很多人可能没有注意到:

num = (double)k/m;

在这里,无论double是强制类型转换了k还是k/m,答案都一样;但这边的double是修饰k的,因为括号的优先级是高于/的;

如果想要double修饰k/m的话就可以这样做:

num = (double)(k/m);

另一个例子:

a  =  (int)father->age;

这里很明显int是修饰age的,因为father是不能强制类型转换成int类型的;这里是因为->的优先级高于括号;

》》》接下来看看有关数据类型的几种例子

case 1:

int a,b=;
a=(int)b;

这里 因为a,b都是int型,所以这边的(int)可以不用,即显式隐式都是可以的;

case 2:

int a;
char b='A';
a=(int)b;
char a;
int b=;
a=(char)b;

首先这个例子能互换是因为字符和整型之间可以通过ascii码转换,其次char占一个字节而int占4个字节;

在前一个大数给小数的情况下,显式隐式编译器都通过,但是很有可能导致溢出,所以需要自己注意;

后一个系统自动会把b扩成4字节赋值给a(b还是1字节)

case 3:

int b=-;
unsigned int a;
a=b;
printf("%d\n",a);

这里unsigned int的范围是0~65535 ,其实当a=b后,a的值是65535,但输出却是-1;我一开始没有想通,加了显式转换之后试了一下还是-1,后来才知道%d输出是有符号的int类型,所以输出结果还是-1;

说到这个我想到之前一个学弟问我%e的问题;

那是书上的一个例子,输入用%e,输出却用%f,他一直奇怪为什么输出是71.820000而不是7.182000e+01;

你不用%e输出,怎么会看到7.182000e+01呢?就算你用%f输入%e输出也能看到这样的形式啊。

我觉得学语言不能光学个语法,重点需要了解数据是如何存在于计算机内部的。

你需要知道无论怎么样输入输出,同样的数据存在计算机里面是不变的,只是我们在屏幕上看到的显示方式不一样而已,就像一个月饼,有包装和无包装它就是个月饼,里面的馅还是那个馅。

扯的有点远了。今天先写到这里发出来吧。下次再补充,EDG炸了我看的很难受= =。

========================================================================================

2015/11/16 补充:

本次补充主要根据《The C Programming Language》

 #include <stdio.h>

 int main()
{
short x = +;//-2 short x1 = ; //取余 但是可以为负数 short x2 = ; //取余后的最小非负整数
unsigned short y = ; //取余后的最小非负整数 printf("x1=%d x2=%d\n" , x1 , x2);
printf("y = %d\n", y );
return ; }

ps

当表达式中包含 u n s i g n e d 类 型 的 运 算 分 量 时 , 转 换 规 则 要 复 杂 一 些 。 主 要 问 题 是 , 在 有 符 号 值与无符号值之间的比较运算取决于机器,因为它们取决于各个整数类型的大小。例如,假定
i n t 对象占 1 6 位, l o n g 对象占 3 2 位,那么,- 1 L < 1 U ,这是因为 i n t 类型的- 1 U 被提升为 s i g n e d l o n g
类型;但- 1 L > 1 U L , 这 是 因 为 - 1 L 被提升为 u n s i g n e d l o n g 类 型 , 因 此 它 是 一 个 比 较 大 的 正 数 。

在进行赋值时也要进行类型转换, = 右边的值要转换成左边变量的类型,后者即赋值表达式
结果的类型。

如前所述,不管是否要进行符号扩展,字符值都要转换成整数值。

当把较长的整型数转换成较短的整型数或字符时,要把超出的高位部分丢掉。

C语言细节——献给入门者(三)的更多相关文章

  1. C语言细节——献给入门者(一)

    C语言细节——献给入门者(一) 主题  输入输出需要注意的细节 首先我们要知道大致有scanf(),printf(),getchar(),putchar(),gets(),puts()这几种输入方式. ...

  2. C语言细节——献给初学者(二)

    C语言细节——献给初学者(二) 主题  循环运用+选择判断 C语言循环有for和while/do...while: 选择判断有:if...else和switch...case 在循环中需要注意搭配br ...

  3. Go 语言入门(三)并发

    写在前面 在学习 Go 语言之前,我自己是有一定的 Java 和 C++ 基础的,这篇文章主要是基于A tour of Go编写的,主要是希望记录一下自己的学习历程,加深自己的理解 Go 语言入门(三 ...

  4. Swift语言Auto Layout入门教程:上篇

    原文:Beginning Auto Layout Tutorial in Swift: Part 1/2,译者:@TurtleFromMars 开始用自动布局约束的方式思考吧! 更新记录:该教程由Br ...

  5. C语言细节总结笔记

    C语言细节总结笔记 */--> C语言细节总结笔记 Table of Contents 1. 三步异或法交换数字 2. 做差法交换数字 3. 按n位置位 4. 求余求商求积 5. 辗除法求最大公 ...

  6. 学习swift语言的快速入门教程推荐

    随着苹果产品越来越火爆,苹果新推出的swift必定将在很大程度上代替oc语言.学好swift语言,对于IOS工程师来讲,已经是一门必备技能. 有一些比较好的英文版教程,值得学习. 1. Swift T ...

  7. 加密入门(三):TrueCrypt(转)

    http://terrychen.info/encryption-truecrypt/ TrueCrypt 是一款功能强大的开源加密工具,利用 TrueCrypt 可以创建一个加密文件作为虚拟加密卷, ...

  8. ElasticSearch入门 第三篇:索引

    这是ElasticSearch 2.4 版本系列的第三篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  9. SpringBoot入门(三)——入口类解析

    本文来自网易云社区 上一篇介绍了起步依赖,这篇我们先来看下SpringBoot项目是如何启动的. 入口类 再次观察工程的Maven配置文件,可以看到工程的默认打包方式是jar格式的. <pack ...

随机推荐

  1. C#中ref和out的使用与区别

    C#中ref关键字和out关键字所实现的功能差不多,都是指定一个形参按照引用传递而不是实参的副本传递.但是二者适用场景还是有些区别的:out适合用在需要retrun多个返回值的地方,而ref则适合用在 ...

  2. OpenGL问题拾遗

    1 OpenGL设置好纹理以后显示不出来,显示为黑色 纹理默认会使用 mipmap .如果没有修改filter选项,或没有指定其他level的mipmap数据,就会显示不出来

  3. JDBC操作

    String sql = "SELECT * from lib where name = ?";List<Lib> list = getJdbcTemplate().q ...

  4. js检测浏览器是否支持某属性

    以检测浏览器是否支持 input 标签的 required 属性为例: var isSupport = 'required' in document.createElement('input');

  5. An AVPlayerItem cannot be associated with more than one instance of AVPlayer错误

    An AVPlayerItem cannot be associated with more than one instance of AVPlayer An AVPlayerItem cannot ...

  6. windows2003安装TestDirector8.0 安装时输入用户名密码 提示错误

    1.TestDirector8.0的安装过程 2.修改错误 右键“我的电脑”->“属性”->"高级"->性能对应的"设置"->" ...

  7. Unit01-OOP-对象和类(上)

    Unit01-OOP-对象和类(上) 1.什么是类?什么是对象?  1)现实生活是由很多很多对象组成的    基于对象抽出了类  2)对象:真实存在的单个的个体    类:类型.类别,代表一类个体  ...

  8. 戴尔商务机OptiPlex5040问题

    windows安装程序无法将Windows配置为在此计算机的硬件 你讲的那个提示准确讲应该是在系统装完重启后进入硬件检测和对应驱动开始阶段,应该是突然提示出来:windows安装程序无法将window ...

  9. 使用maven来管理您的java项目

    maven是一个项目管理工具,使用maven可以自动管理java项目的整个生命周期,包括编译.构建.测试.发布和报告等.在大型项目开发中,使用maven来管理是必不可少的. 一.安装maven 1.W ...

  10. MVC HtmlHelper用法(一)@Html.BeginForm的使用总结

    1.@using(Html.BeginForm()){}                                                      //提交到当前页面 2.@using ...