整形数,浮点数
来源:互联网 发布:梦幻西游账号数据 编辑:程序博客网 时间:2024/04/28 14:56
一说到数字,我们脑子里就会闪现出一些数字的类型,比如,int,double,float,long,当然还有一些复合类型,比如
指针类型,枚举类型,结构体类型等等。关于这些类型的变量在内存中所占的字节数到底是多少,下边我来给出测试:
windows系统vs编译器下:
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdbool.h>int main(){printf("%d\n",sizeof(char));printf("%d\n", sizeof(short));printf("%d\n", sizeof(int));printf("%d\n", sizeof(long));printf("%d\n", sizeof(long long));printf("%d\n", sizeof(float));printf("%d\n", sizeof(double));printf("%d\n", sizeof(long double));printf("%d\n", sizeof(bool));system("pause");return 0;}运行结果如下:
或许,你到现在还以为c语言里没有bool类型,其实,c99已经引入了,只是使用的时候你需要加头文件而已。
同样的代码,拿到linux的gcc下试试,看看运行结果吧。
只有long double的大小不同,其他的应该都一样。要是在g++下还会有不同,你可以试试。
指针类型的大小,32位系统下都是4.结构体的大小,前边那篇文章中已经有讲过。
(一)整形数
1.整形数的类型有:int,signed int,unsigned int(size_t),short,long,long long等等。
2.整形提升:
c语言中的数据类型转换分成两种 ,一种是隐式类型转换,一种是显式类型转换(强制类型转换)。强制类型转换
我们见的比较多了(比如动态内存分配函数里....),这里就只给出隐式类型转换。
当不同的数据类型的数进行计算时,就会发生隐式类型转化,隐式类型转换的步骤:(1)表达式中的char,short都
变成int,float变成double。(2)根据参与计算的数据类型从低精度向高精度转换。
精度低到高:char,short -> int -> unsigned int -> long ->double
float->double
下边给出几个实例:
实例1:
int a = INT_MAX;int b = 2;long long c = a + b;long long c = (long long)(a + b);long long c = (long long)a + b;
分析上边的表达式。
long long c = a + b;//发生溢出。首先计算的是a+b,都是int,已经发生溢出,再转换,当然是没用啦~~
long long c = (long long)(a + b);//原因类似上边,已经发生了溢出,才进行 转换。
long long c = (long long)a + b;//正确,b被隐含转换成long long
实例2:下边代码的运行结果是什么??
int main(){unsigned char a = 200;unsigned char b = 100;unsigned char c = 0;c = a + b;printf("%d %d",a+b,c);system("pause");return 0;}
怎么感觉输出结果是300 300呢??其实并不是。我来分析一下。由于a和b都是无符号 char型,进行运算都会发生整
形提升。都被提升为int。所以执行c = a + b时,
a被提升为:00000000 00000000 00000000 11001000
b被提升为:00000000 00000000 00000000 01100100
a+b: 00000000 00000000 00000001 00101100
由于c是一个字节,所以a+b会被截断,变成00101100,即10进制的44
而直接输出a+b的值时,32个比特位,结果是300.
实例3:
int main(){char c;unsigned char uc;unsigned short us;c = 128;uc = 128;us = c + uc;printf("0x%x ",us);us = (unsigned char)c + uc;printf("0x%x ", us);us = c + (char)uc;printf("0x%x ", us);system("pause");return 0;}
这道题看起来好像比较头疼。不过,没关系,干程序员这一行,需要的是细心,耐心,哈哈。
c = 128.由于它是有符号数,所以8个比特位中1位是符号位,7位是实际的数.128就是10000000。然而,它的第一位
表示符号。进行整形提升时,被提升为 11111111 11111111 11111111 10000000.
uc = 128.由于它是无符号数,所有的比特位都表示实际数字。128是10000000,进行整形提升时,被提升为:
00000000 00000000 00000000 10000000
两个进行相加,取后边的16个比特位,结果是0,也是16进制的0.
当c被强制转化成无符号整形时,128的二进制中的首位1并不表示符号,进行整形提升时,被提升为:
00000000 00000000 00000000 10000000
再与uc相加,1取低位的16个比特位,结果是256,即就是16进制0x100
当uc被强制转化成有符号char时,128的二进制中的首位1表示符号,进行整形提升时,被提升为:
11111111 11111111 11111111 10000000
与c相加之后,取低位的16个比特位,结果是0xff00.
所以程序的输出结果是:0x0 0x100 0xff00
3.上边代码出现了INT_MAX,下边就此问题展开说明。
在《c语言点滴》(赵岩著)这本书中3.10节关于整形数和浮点数给出一个口诀:296两宏两头。29表示整形数的上
限是2*10^9,6表示浮点数的有效位是6位,两宏指的是_MAX类型宏 和EFLT_PSILON类型宏 ,两头指的是float.h和
limits.h。
关于这两个头文件:
float.h中主要给出浮点数,double数的最小值,最大值,等等。下边给出部分。
limits.h中给出整形数的范围,可以自行查看。
下边给出整形数这块的重点例题:
例1:
unsigned char c = -1;printf("%u",c);%u是无符号整形的形式。unsigned c = -1,在计算机中以补码形式存储,即为1111 1111,计算机会认为它是一个正
数当它变成无符号整形时,前边补24个0,最终就是255.
无符号char是一个字节(32位系统)。
例2:
char c = -128;printf("%u",c);
最终的结果是,c = 11111111 11111111 11111111 10000000
-128:原码;1 1000 0000反码:1 0111 1111 补码:1 1000 0000
计算机会认为c是一个有符号的字符型,变成无符号数整形时,前边补24个1.
总结:如果是无符号数,小范围->大范围:前边补0
如果是有符号数,小范围->大范围,前边补符号位。
例3:
int i = -20;unsigned int j = 10;printf("%d",i + j);程序的运行结果是-10,请看分析过程:
-20原码:10000000 00000000 00000000 00010100
反码:11111111 11111111 11111111 11101011
补码:11111111 11111111 11111111 11101100
10原码:00000000 00000000 00000000 00001010
反码:01111111 11111111 11111111 11110101
补码:01111111 11111111 11111111 11110110
两个补码相加之后转换成原码:10000000 00000000 00000000 00001010 就是-10
例4:
char a[1000];int i = 0;for(i = 0;i < 1000;i++){ a[i] = -1 - i;}printf("%d",strlen(a));
看看上边这段代码执行后的结果是什么。strlen可以求字符数组的长度,找\0,找到为止。
所以,i = 0时,a[0] = -1,a[i]就是-1,-2,......,-128,下来就是127,....,1,0(相当于是上边的椭圆逆时针转一
圈,0就是结尾符了,\0的ascii是0)。所以,strlen (a) = 128+127 = 255.
(二)浮点数
在IEEE754标准中,给出了V = (-1)^s*M*2^E(1<=M<2)
s代表符号,M是尾数,E是阶码。E = e+偏移位。
32位浮点数和64位浮点数的标准格式,如下图 :
知道这些之后,我们就应该推导一下浮点数的表示范围。下图以32位浮点数为例(64位的可以自己整理)
下边看一道例题:
int num = 9;float *pfloat = (float *)#printf("%d ",num);printf("%f ",*pfloat);*pfloat = 9.0;printf("%d ",num);printf("%f ",*pfloat);分析:第一个printf输出9毫无疑问。
第二个printf,pfloat是指向浮点数的指针。所以系统便认为9(0 00000000 00000000000000000001001)是
一个浮点数。阶码E = 0,所以该数是无限接近于0的数,所以输出0.
第三个printf,*pfloat在内存中表示为:0 10000010 00100000000000000000000,若以%d输出,就是一个比
较大的数。即就是01000001000100000000000000000000表示的整形。
第四个printf,输出9.0。也没什么问题。
关于数字,就整理这么多,如果有不合理的地方,希望指出~
- 整形数,浮点数
- 字符串,整形数,浮点数之间的转换
- 整形数和浮点数在内存中的存储方式
- JavaScript限制文本框只能输入整形或浮点数类型
- JS限制文本框只能输入整形或浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 浮点数
- 基于CSS和JavaScript创建动画式谷歌地图标记
- iOS学习之——NSString
- 自定义控件--View篇学习总结
- linux误操作删除掉var(rm /var/*)目录导致的问题,及解决方法
- DHCP
- 整形数,浮点数
- 线程
- Navicat修改MySQL数据库密码就是这么简单
- Android Studio 快捷键使用
- BabeLua秒启调试补丁1.08,支持Quick, 支持VS2013和VS2015(2016.6.21更新)
- Python 猜数字小游戏 (带闯关关卡)
- VB script 入门
- 如何使用shape来画半圆和画虚线
- 如何将pdf转换成ppt幻灯片