C语言——数据类型
C语言中的数据类型种类
数据类型可分为基本数据类型(整型,浮点型,字符型,枚举类型),构造数据类型(数组类型,结构体类型,共用体类型),指针类型,空类型四大类。下面主要讲述的是基本数据类型中的整形,浮点型,字符型。
为什么要划分数据类型呢?
我的理解是,不同的数据类型所占用的内存空间不同,表示的数据范围和数据精度不同,所支持的应用场景也不同,通过划分不同的数据类型可以根据不同的应用场景选择合适的数据类型。
要想了解数据类型就必须先了解常量和变量,那什么是常量什么是变量呢?
按照定义常量就是在程序运行的过程中(该过程是指在编译完成后执行输出结果之前的过程)不能被改变的量;而变量就是在程序运行的过程中可以被改变的量,变量之所以能够改变是因为变量是一块能够被改变的空间。
整型
整型的常量形式
例如:十进制:123,456,…;八进制:0123,0456,…;十六进制:0x12,0x23…。
整型的变量形式
变量的定义:数据类型 变量名;
例如:int i; 这就是定义了一个名为i的整型数据。
变量定义的规则:
1、变量名只能由数字、字母、下划线组成;
2、数字不能作为变量名的开头;
3、变量名不能与关键字重名(因为如果变量名与关键字重名的话编译器在编译时就难以辨别变量的关键字);
4、不能与预处理命令和库函数名重名;
变量在内存中的存储方式:
要想知道变量在内存中是以一种什么样的方式存储就先要知道大端和小端存储,所谓小端存储就是高位数据在高位地址存储,低位数据在低位地址存储;而大端存储就是高位数据在低位地址存储,低位数据在高位地址存储。在x86的体系结构中都是以小端的形式存储,而51单片机是以大端的方式存储。
整型类型的分类
整型又可以分为int、short、long、long long四种类型;
整形数据类型的大小:int 4个字节
short 2个字节
long 8个字节
long long 8个字节
上述数据类型大小可以通过sizeof(运算数)运算出来,其中运算数可以是数据类型时表示的含义时该数据类型在内存空间中所占的字节数。运算数还可以是变量名、常量或者是表达式。
整型数据在内存中的存储
整型数据在内存中最终的都是以补码的方式存储,那么什么是补码呢?
补码 = 反码 + 1;
对于一个无符号(unsigned)数它的原码,反码,补码都是一样的;
对于一个正整数(siged)它的原码,反码,补码都是一样的;
对于一个负整数(signed)它的最高位为符号位其余位为数值位,它的原码、反码(符号位不变其他位取反)、补码如下:
例如:-2
原码:1000 0000 0000 0000 0000 0000 0000 0010
反码:1111 1111 1111 1111 1111 1111 1111 1101
补码:1111 1111 1111 1111 1111 1111 1111 1110
说明标记处位=为符号位。
整型数据类型的取值范围:
int 4字节
unsigned int 0~2^32-1
signed int -2^31 —— 2^31 - 1
short 2字节
unsigned short 0~2^16-1 //65535
signed short -32768 ~ 32767
long 8字节
long long 8字节
无符号整型数据溢出问题
#include<stdio.h>
int main(void)
{
int i = 0;
for(i = 0; i <= 65535; ++i)
{
printf("%d\n", i);
}
return 0;
}
上述代码编译运行后程序会陷入死循环,原因是当i加到65535再++i时i又继续变成了0,0<=0<=65535满足循环条件继续执行循环语句,从而使得程序陷入了死循环。
数据的存储和使用是分开的
浮点型
常量形式:如:1.23、1.23e-4、1.23E-4…;
变量形式:
关键字:float(单精度)、double(双精度)、long double;
变量定义的方式:
数据类型 变量名;
如:float a;
浮点型的大小
float(单精度) 4字节;
double(双精度) 8字节;
long double 8字节;
浮点型数据的存储
浮点型数据在内存中仍然是用补码来存储,此时就必须知道浮点类型数据的补码的转换方法:
1、先分别将浮点数的整数和小数部分分别转换为二进制,小数转而进制的方法时小数 * 2取整数直到数据变为1;
2、将二进制的浮点数写成科学计数法的形式;
3、按照 IEEE 754 标准 存放
float类型(4个字节32个位)的数据补码:
1位符号位8位指数位 + 偏移量127、23位尾数位;
double类型(8个字节64个位)的数据补码:
1位符号位11位指数位 + 偏移量1023、52位尾数位;
以float类型数据为例:
-6.125的补码:
第一步:110.001
第二步:1.10001e-2
第三步:符号位为1,指数位2+偏移量127 = 129转为二进制为1000 0001,尾数位为10001
综上-6.125的补码为:1100 0000 1100 0100 0000 0000 0000 0000
以十六进制表示就是:0xc0c40000
浮点数的比较问题
#include <stdio.h>
int main(void)
{
float a = 0.9;
if(a == 0.9)
{
puts("yes\n");
}
else
{
puts("no\n");
}
return 0;
}
运行编译上述代码知道程序得输出结果为no,原因是代码中出现的浮点型常量默认是别为double类型,也就是说if(a == 0.9)中得0.9数据类型是double而a得数据类型是float二者类型不同精度也不同所以程序的输出结果是no解决办法是把a得数据类型改为double。
字符型
字符型数据就是用二进制数据给字符编号;
字符常量:‘a’、‘A’、…
字符变量:char ch = ‘a’、char ch = ‘A’;
字符型得大小为一个字节,例如一个’a’字符在内存中保存的是这个字符对应的ASCII码值,char也是一种整型类型,所有说char和整型是通用的。
常见字符对应的ASCII码值:
0~32:控制字符;
48~57:数字字母;
65~90:英文大写字符;
97~122:英文小写字符;