(代码运行环境:Xcode7.3.1)
先来看这段代码
#include <stdio.h>
int main() {
int a = 0x12345678;
int i = 0;
printf("0x%x, 0x%x\n", &a, a);
for(; i < sizeof(a); i++) {
printf("0x%x, 0x%x\n",(char *)&a +i, *((char *)&a + i));
}
return 0;
}
输出:
0x5fbff7c8, 0x12345678
0x5fbff7c8, 0x78
0x5fbff7c9, 0x56
0x5fbff7ca, 0x34
0x5fbff7cb, 0x12
得出结论:在内存中,数是倒着存储的;
87 65 43 21
整形的存储方式
运行此代码
我们把Int类型拆开来看,分成4个字节看(32位)
#include <iostream>
#include <vector>
void c_to_b(unsigned char c, std::vector<int> &ve) { // 十进制char类型转换为二进制
int st[8];
for(int index = 7; index >= 0; index--) {
st[index] = c % 2;
c >>= 1;
}
for (int index = 0; index < 8; index++) {
ve.push_back(st[index]);
}
}
void int_to_char(int interge) { // int类型转化为char类型,而且以二进制输出
std::vector<int> ve;
union {
int a;
struct {
unsigned char a1, a2, a3, a4;
} st;
} un;
un.a = interge;
c_to_b(un.st.a1, ve); // 明显体现出。倒着存储的
c_to_b(un.st.a2, ve);
c_to_b(un.st.a3, ve);
c_to_b(un.st.a4, ve);
for (int index = 0; index < 8; index++) {
std::cout << ve[index];
}
std::cout << " ";
for (int index = 8; index < 16; index++) {
std::cout << ve[index];
}
std::cout << " ";
for (int index = 16; index < 24; index++) {
std::cout << ve[index];
}
std::cout << " ";
for (int index = 24; index < 32; index++) {
std::cout << ve[index];
}
}
int main(int argc, const char * argv[]) {
int_to_char(-2);
return 0;
}
-2 :11111110 11111111 11111111 11111111
低位 高位
2: 00000010 00000000 00000000 00000000
-5: 11111011 11111111 11111111 11111111
结论:
1 数据倒着存储
2 负数在计算机中是以该负数的二进制的补码形式
存储的。
比如2的反码是 11111101 11111111 11111111 11111111
补码是(反码 + 1 ,在低位加1) 11111110 11111111 11111111 11111111
在有符号数中,正数第一位是0,负数第一位是1
(高位字节的第一位就是符号位)
浮点型的存储方式
float 单精度浮点型 1位符号位 8为阶码位 23位尾位
double 双精度浮点型 1位符号位 11位阶码位 52位尾位
以double为例
void d_to_b(double d) { //double转化为内存中的二进制表示
std::vector<int> ve;
union {
double a;
struct {
unsigned char a1, a2, a3, a4, a5, a6, a7, a8;
} b;
} t;
t.a = d;
c_to_b(t.b.a8, ve); // 已经确实是倒着存储了,这里手动把他反过来
c_to_b(t.b.a7, ve);
c_to_b(t.b.a6, ve);
c_to_b(t.b.a5, ve);
c_to_b(t.b.a4, ve);
c_to_b(t.b.a3, ve);
c_to_b(t.b.a2, ve);
c_to_b(t.b.a1, ve);
std::cout << "符号位:" << ve.at(0) << " ";
std::cout << "阶码:";
for (int index = 1; index < 12; index++) {
std::cout << ve.at(index);
}
std::cout << std::endl << "尾码:";
for (int index = 12; index < 64; index++) {
std::cout << ve.at(index);
}
std::cout << std::endl;
}
7.3:
符号位:0 阶码:10000000001
尾码:1101001100110011001100110011001100110011001100110011
7.5:
符号位:0 阶码:10000000001
尾码:1110000000000000000000000000000000000000000000000000
来看一道题目
printf("%d",7.5f); // 输出是多少?
(在VS2005上运行的时候是0 ,在Xcode里是一堆数)
解释一下为什么是0,7.5f在内存中的存储已经知道了,而%d是读取32位,很明显尾数的7.5f都是0
也不是所有浮点数这样输出都是0,试试7.4
在Mac中尝试了一下,。。。竟然是随机数。。。神奇的事情,有待研究。
指针的应用
指针是从低位开始的
int main(int argc, const char * argv[]) {
int num = 1;
int *p1 = #
char *p2 = p1;
char *p3 = p2 + 1;
*p3 = 3;
printf("%d", *p1);
return 0;
}
// 低位 高位
// 00000001 00000000 00000000 00000000
// p1
// p2
// p3
// 00000001 00000011 00000000 00000000
// 倒回来读00000000 00000000 00000011 00000001 = 512+256+1