1 数据类型介绍
1.1 C语言基本内置类型
大小(字节) | 类型 | |
char | 1 | 字符串数据类型 |
short | 2 | 短整型 |
int | 4 | 整型 |
long | 4(32位机器上是4字节) 8(64位机器上是8字节) | 长整型 |
long long | 8 | 更长的整型 |
float | 4 | 单精度浮点数 |
double | 8 | 双精度浮点数 |
1.2 类型的意义
1.使用这个类型开辟空间内存的大小(大小决定了使用范围)
int a= 0 ;
系统申请四个字节给a,那么a就可以用这四个字节来表示一个整型数值,取值范围为-2147483648~2147483647。
2.如何看待内存空间的视角
int a = 0 ;
float b = 0 ;
系统给a与b都申请了四个字节,但是看待它们是不一样的,系统认为a是整型,b是单精度浮点型。
1.3 类型的基本归类
1.3.1 整型家族
char
unsigned char
signed char
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]
注:[]是可省略的意思
1.3.2 浮点型家族
float
double
1.3.3 构造类型
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
1.3.4 指针类型
int *pi;
char *pc;
float *pf;
void *pv;
1.3.5 空类型
void表示空类型
通常用于函数的返回类型、函数的参数、指针类型
2 整型在内存中的存储
一个变量的创建时在内存中开辟空间的。空间的大小是根据不同的类型决定的。
我们接下来将会解释数据在所开辟内存中到底是如何存储的。
例如:int a=10; 与 int b=-10;在内存中存储的方式与区别
2.1 原码、反码、补码
2.1.1 计算机中整数的三种2进制表示方法
计算机中的整数有三种2进制表示方法,即原码、反码和补码。
2.1.2 原码、反码和补码的组成
原码、反码和补码均是有符号位和数值位两部分组成,符号位都是用0表示“正”,用1表示“负”。数值位正整数的原码、反码和补码都是一样的,而负整数的三种表示方法各不相同。
2.1.3 负整数的三种表示方法
原码:直接将数值按照正负数的形式翻译成二进制就可以得到原码
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码
补码:反码+1得到补码
以-5为例
原码:10000000 00000000 00000000 00000101
反码:11111111 11111111 11111111 11111010
补码:11111111 11111111 11111111 11111011
2.1.4 数据存放内存中的其实是补码
为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(cpu只有加法器)此外,补码和原码相互转换的过程是相同的,不需要额外的硬件电路。
以-5为例,展示根据补码求原码的两种计算方法步骤:
-5的补码:11111111 11111111 11111111 11111011
1.根据求原码、反码和补码的方法逆用,来得出原码
补码-1=反码
反码:11111111 11111111 11111111 11111010
反码除符号位不变,其他位按位取反得到原码
原码:10000000 00000000 00000000 00000101
2.按照原码转换成补码的方法
符号位不变,其他位按位取反
100000000 00000000 00000000 00000100
加一得到原码
100000000 00000000 00000000 00000101
由此可见,结果是一样的。
加法和减法
6-5=1
6的补码即原码: 00000000 00000000 00000000 00000110
-5的补码: 11111111 11111111 11111111 11111011
-----------------------------------
6-5的结果是: 00000000 00000000 00000000 00000001
存补码实现了加法和减法运算方法的统一,这样就不需要额外的减法器
2.2 大小端介绍
它们的在内存中存储的顺序是像上面写的那样吗?
int a=5;
int b=-5;
注:内存1是a地址,内存2是b地址。
由此可见,并非是按照正着放(00 00 00 05以5为例)的形式放的,而是数值的低位放在了低地址上,高位放在了高地址上
2.2.1 什么是大小端
大端[存储]模式:数据的低位放在内存的高地址中,数据的高位放在内存的低地址中(低放高,高放低)
小端[存储]模式:数据的低位放在内存的低地址中,数据的高位放在内存的高地址中(低放低,高放高)
0x11223344
数据:高位-----<------低位
内存: 地位----->------高位
2.2.2 为什么要有大端和小端
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应一个字节,一个字节为8bit。但是在c语言中除了8bit的char之外,还有16bit的short型,32bit的long型,另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题,因此就导致了大端存储模式跟小端存储模式。
2.2.3 关于大端小端的练习
百度2015年系统工程师笔试题
请简述大端字节序和小端字节序的概念,设计以恶搞小程序来判断当前机器的字节序。
分析:
int a = 1 ;
如果是小端那么就是
01 00 00 00
如果是大端那么就是
00 00 00 01
&a是int *类型
*(char*)&a
char*可以截取a地址值的前一个字节。
*(char*)&a=1的话就是小端,否则就是大端
#include<stdio.h>
int check_sys()
{
int i=1;
return (*(char*)&i);
}
int main()
{
int ret=check_sys();
if(ret==1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
reurn 0;
}