大家都知道一个变量的创建是要在内存中开辟空间的。而空间的大小又是根据不同的变量类型而决定的。
接下来就详细讲解一下数据在内存中是怎么存储的。
首先我先来举一个例子:
#include<stdio.h>
int main()
{
int a = 20;
int b = -10;
return 0;
}
我们来看一看变量a,b在内存中的分布:
在结合下面这幅图:
大家应该能够直观的看出,数据在内存中是以二进制的补码来存储的。
但是细心的人应该能够发现,计算机存储的16位进制顺序和我们人工手写的16位进制的顺序不同,这就牵扯到了大小端的概念了。
大端:指数据的低位保存在内存的高地址中,而数据的高位则保存在低地址中。
小端:指数据的低位保存在内存的低地址中,而数据的高位则保存在高地址中。
大小端是由系统决定的,我们常用的x86模式是小端结构,而KEIL C51则是大端模式。
那么能不能测试一下自己的电脑是小端还是大端呢?
测试代码如下:
#include<stdio.h>
int main(){
int i = 1;
char c = (char)i; //将int i 强转化为char,发生了整形的截断
if (c == 1){ // 正数的原反补相同 1的补码为
printf("是小端\n"); //00000000 00000000 00000000 00000001
} //int在内存中占4个字节,char只占1一字节,当发生整行的截断时,char只会获得int的低8位,其余的全部丢弃。
else // 只剩下 00000001 即正数 1
{ //若是小端 则应该获得 1
printf("是大端\n"); //若是大端 则应该获得 0
}
return 0;
}
既然int -> char 会发生整数的截断,那么对应的char -> int 就是发生整数的提升。
例如以下的代码会输出什么:
#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;
}
结果为:
原因是在整形提升过程中,分为有符号数提升和无符号数提升。
有符号数提升:在截断处前补原码的符号数,即整数补0,负数补1.
无符号数提升:在截断处前补0.
具体如下所示:
这就是整形的截断和提升了。