数据在内存中的储存(一)
一、整型在内存中的储存
我们之前讲过一个变量的创建是要在内存中开辟内存空间的。空间的大小是根据不同的类型而决定的。
我们知道int a=0;为a分配四个字节的空间,那如何储存?
对于整型来说:数据存放内存中实际存放的是补码。
原码:直接将二进制按照正负数的形式翻译成二进制就可以;
反码:将原码的符号位不变,其他位依次按位取反就可以得到;
补码:反码+1就得到。
正数的原、反、补码都相同。
eg:内存中的储存:
Int a=-10; 内存中:(小端模式) 0X f6 ff ff ff
f f->1111 1111 f f->1111 1111 f f->1111 1111 f 6->1111 0110
11111111111111111111111111110110-补码
11111111111111111111111111110101-补码-1得到反码
10000000000000000000000000001010-符号位不变,其他位取反 得到原码
根据原码得 -10
二、大小端
大端存储模式:数据的低位保存在内存的高地址中。
小端存储模式:数据的低位保存在内存的低地址中。
下面展示一些 内联代码片
。
设计一个小程序来判断当前机器的字节序:
#include<stdio.h>
int check()
{
int i = 1;
char *p = (char*)&i;
return *p;
}
int main()
{
int ret = check();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
三、整形提升
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器的操作的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器长度。
因此,即使是两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。
通用CPU是难以直接实现两个8比特字节直接相加运算的。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int 或 unsigned int ,然后才能送入CPU去执行运算。
Eg :char a,b,c;
a=b+c;
b和c的值被提升为普通整型,然后再执行加法运算。加法运算完成后,结果将被截断,然后再存储于a中。(要根据char的符号类型来提升,比如:unsigned char:高位补零;signed char:按符号位提升)
练习
下面展示一些 内联代码片
。
#include<stdio.h>
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a=%d,b=%d,c=%d", a, b, c);
return 0;
}
内存中int a的补码是:
11111111111111111111111111111111
char a的补码是(截断后):
11111111
打印整形printf(“a=%d”,a),因为char a是signed char a所以按符号位进行提升,提升后:
11111111111111111111111111111111
unsigned char c=-1;
截断后:11111111
打印整形printf(“c=%d”,c),因为unsigned char a是无符号类型,所以提升时做无符号提升:采用高位补0的方式,提升后:
00000000000000000000000011111111
因为正数的原码、反码、补码相同,所以int c=255