#define _CRT_SECURE_NO_WARNINGS 1
**整形存储**
#include <stdio.h>
int main()
{
int a = 10;
int b = -10;
return 0;
}
调试,打开内存输入&a,地址后面的内容为00 00 00 0a;此时为十六进制;
大端(存储)模式:数据低位存到内存高地址中,数据高位存低地址中;(数据与内存相同顺序摆放)
小端(存储)模式:数据低位存到内存低地址中,数据高位存高地址中;
数据高地址--如0x11 22 33 44中11为数据高位;内存高地址--右为高位,从左到右增高
设计程序判断当前机器的字节序(大小端)
#include <stdio.h>
int main()
{
int a = 1;
char* p = (char*)&a; //(char*)&a--强制选取(不改变)a的地址的第一个字节(最左边的字节)
printf("%d\n",*p);
if (*p == 1) //*p--根据地址找到对应的对象
{
printf("小端存储");
}
else
{
printf("大端存储");
}
return 0;
}
指针类型的意义
1.决定了指针解引用操作符能访问几个字节
2.决定了指针+1,-1加减几个字节
#include <stdio.h>
int main()
{
int a = 0x11223344;
int b = 0x11223344;
int* pa = &a;
*pa = 0;
char* pb = (char*)&b;
*pb = 0;
return 0;
}
查内存&a为00000000 b为00332211
#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;
}
输出结果为-1 -1 255
-1的整形提升后的原码--10000000000000000000000000000001
反码--11111111111111111111111111111110
补码--11111111111111111111111111111111
a,b,c定义的是char,只能存1字节,发生截断后存入补码
a,b,c--11111111 -- 补码
当要打印时%d是整形,发生整型提升再到回原码打印
char含有符号位,高位为1补1--11111111111111111111111111111111-补码
signed char,与char相同
unsigned char不含有符号位高位补0--00000000000000000000000011111111--补码
正数原反补相同--c为255
#include <stdio.h>
int main()
{
char a = -128;
printf("%d\n", a);
printf("%u",a); //%u打印十进制的无符号数字 %d打印十进制的有符号数字
return 0;
}
-128--100000000000000000000000010000000
--111111111111111111111111101111111
--111111111111111111111111110000000 补码
打印 a-10000000
整型提升 111111111111111111111111111000000 补码
%u无符号打印,把上个补码当成无符号数,返回原码
打印 111111111111111111111111111000000(4294967168)
有符号char范围为-128~127 --char,signed char
00000000--0(补码)正数原反补相同
00000001--1
...
01111111--127
10000000--规定此补码对应原码为 -128
10000001-- 10000000(反)--11111111(原)-- -127
...
11111111--11111110--10000001-- -1
无符号char范围为0~255 --unsigned char
00000000--0
...
11111111--225
#include <stdio.h>
int main()
{
char a = 128;
printf("%d\n", a);
printf("%u", a);
return 0;
}//
128--00000000000000000000000010000000
--00000000000000000000000010000000
--00000000000000000000000010000000
10000000
%d-- 11111111111111111111111110000000
11111111111111111111111101111111
10000000000000000000000010000000-- -128
%u-- 00000000000000000000000010000000
00000000000000000000000001111111
11111111111111111111111110000000-- 4294967168
#include <stdio.h>
#include <string.h>
int main()
{
char a[1000];
int i = 0;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a));//strlen到\0或0停止计算
return 0;
}
当i=0时a[0]=-1,....a[127]=-128...a[128]=127...a[244]=1,a[255]=0,0前共255个数
#include <stdio.h>
int main()
{
unsigned char a;
for (a = 0; a <= 255; a++)
{
printf("hello\n");
}
return 0;
} //死循环
**浮点型存储**
十进制9.0 -- 二进制1001.0 --(-1)^0 * 1.001 * 2^3
(-1)^S * M * 2^E
s--0 , M--1.001(1<=M<=2) , E--3
对于32位(bit)的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M
对于64位(bit)的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M
因为M的第一位总是1,于是不保存,当读取时再加上去,23位的M相当于可以存储24位有效数字
E为无符号整数,如果E为8位,其取值范围为0~225,11--0~2047,但科学计数法中E可以为负数
于是存入内存时E的真实值要加上中间数,8位E为127,11位E为1023,比如存10时要存入10001001
E为全0:规定E的真实值为-126或-1022,且有效数字M不再加上首位的1。直接以 0.xxx*2^(-126)表示
E为全1:正负无穷大
float f=5.5--二进制101.1(0.5=1*2^(-1))-- (-1)^0 * 1.101 * 2^2
S=0,M=1.101,E=2
0 10000001(存储值129) 011 00000000000000000000(补全)
0100 0000 1011 0000 0000 0000 0000 0000
化为16进制0x40b00000
#include <stdio.h>
int main()
{
int a = 9;
float* p = (float*)&a; //访问4个字节
printf("a的值为:%d\n", a); //a--00000000 00000000 00000000 00001001
printf("*p的值为:%f\n\n", *p);//*p--0 00000000 00000000000000000001001(补码)
//E为全0,原码化为十进制前数位全为零
*p = 9.0;
printf("a的值为:%d\n", a); //*p--0 10000010 00100000000000000000000 (补码)
printf("*p的值为:%f\n", *p); //a--01000001 00010000 00000000 00000000(补码)
} //正数原反补相同 a的值为:1091567616