本篇博客将重点介绍以下内容:
- 数据类型
- 整型在内存中的存储:原码,反码,补码
- 大小端字节序介绍及判断
1.数据类型详细介绍
C语言内置类型有:char(字符型 1字节) ,short(短整型 2字节), long(长整型 4字节), long long(更长的整型 8字节 ), float(单精度浮点型 4字节), double(双精度浮点型 8字节) ;
字符型(char)在存储的时候,存储的是字符的ASCII码值,ASCII是整数
数据类型 | 无符号 | 有符号 |
char | unsigned char | signed char |
short | unsigned short | signed short |
int | unsigned int | signed int |
long | unsigned long | signed long |
有正负的数据可以存放在有符号的变量中,只有正数可以存放在无符号的变量中。
平常定义变量时:int a = 0;默认为 signed int
有符号数,最高位为符号位,1表示负数,0表示正数。对于无符号数来说,最高位也是数据位
浮点数类型:float , double, long double
构造类型 (自定义类型):数组类型,结构体类型 (struct) ,枚举类型 (enum),联合类型 (union)
指针类型:int *pi ; char * pc ; float * pf ; void * pv;
2.整型在内存中的存储
一个变量的创建是要在内存中开辟空间的,空间的大小是根据不同的类型而决定的
首先来了解一下原码,反码和补码,计算机中的整数有这三种表示方法 。原码:直接将数值按照正负数的形式翻译成二进制就行,正整数的原码,反码,补码一样
对于负整数,其补码与原码不同,得到补码的方法:先得到反码:符号位不变,其他位按位取反,再把反码加1即得到补码
举个例子:int a = -1;int 类型四个字节
-1的原码:10000000 00000000 00000000 00000001
-1的反码:1111 1111 1111 1111 1111 1111 1111 1110 //符号位不变,其他位按位取反
-1的补码:1111 1111 1111 1111 1111 1111 1111 1111
计算 1+(-1),同样,不能直接用它们的原码计算,应该换成补码进行计算
1的补码与原码相同: 00000000 00000000 00000000 00000001
-1的补码 : 1111 1111 1111 1111 1111 1111 1111 1111
结果: 11111 1111 1111 1111 1111 1111 1111 1111
最高位的1放不下丢失,所以最后结果为0;
在计算机系统中,数值一律用补码来表示和存储,原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
看看下面的题目:
结果为:
%u打印无符号数 , 变量ch 为无符号数,可是负数是不能存储在无符号变量中的
先写出-10的原码:10000000 00000000 00000000 00001010
-10的反码: 1111 1111 1111 1111 1111 1111 1111 0101
-10的补码: 1111 1111 1111 1111 1111 1111 1111 0110
整型在计算机中以补码形式存储,打印无符号数,最高位为数据位,相当于-10的补码存储的是一个正数,原码与-10补码相同
3.大小端介绍及判断
大小端字节序存储分为大端字节序存储和小端字节序存储
例如:int a = 0x11223344;
用四个字节存放a的值,11 22 33 44,从低地址到高地址怎样存放呢?
大端字节序:把一个数据低位字节处的数据存放在高地址处,把高位字节处的数据存放在低地址处
小端字节序:把一个数据高位字节处的数据存放在低地址处,把低位字节处的数据存放在高地址处
例如:一个16bit 的short 类型a,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节
对于大端模式,就将0x11放在低地址处,即0x0010中,0x22放在高地址处,即0x0011中,小端模式,刚好相反。我们常用的x86结构是小端模式,而KEIL C51则为大端模式,很多的ARM,DSP都为小端模式,有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。
那么,我们如何编写代码来判断目前使用的机器是大端还是小端呢
最后,再看一题来加深理解
-1的补码:1111 1111 1111 1111 1111 1111 1111 1111
但是整型四个字节要存放在 char 类型的变量中,大小为一个字节,要发生截断,1111 1111
a,b同理截断后都为 1111 1111,%d最后打印的是整数,要发生整型提升,按照其类型来补,有符号数高位补符号位:
1111 1111 1111 1111 1111 1111 1111 1111 //补码
%d打印的是原码,要换成原码,减1先得到反码:1111 1111 1111 1111 1111 1111 1111 1110
原码:1000 0000 0000 0000 0000 0000 0000 0001
所以,a, b打印的结果都为 -1
c是无符号数整型提升直接补0:00000000 00000000 00000000 11111111补码为正数,正数的原码和补码相同,所以结果为255.