在冯诺依曼体系结构下.内存是非常重要的组成部分!
int NNN = 9;
小端字节序: 数字的低位存储早内存的低地址上 (09 00 00 00 ) ----->简单记忆为: 小 小 小
大端字节序: 数字的低位存储在内存的高地址上 (00 00 00 09)
格列佛游记中小人国讨论的问题就是: 吃鸡蛋时候,是从大头开始磕,还是从小头开始磕鸡蛋. >> 这个问题类似于大小头磕鸡蛋的问题,大端字节序存储符合人的直觉,以后可以方便记忆:吃鸡蛋从大头开始磕
int isLittleEnd(int* p) {
char* p2 = (char*)p;
if (*p2 == 0x44) {
return 1;
}
return 0;
}
减法: 加负数
乘法: 多加n次自身
除法:多减n次自身
正数的原码,反码,补码是一样的!!!
负数的存在运算关系: 补码 = 反码 + 1 ;
原码 = 补码de反码 + 1;
反码 = 原码除符号位取反
%d 表示的是: 打印一个有符号的 十进制的整数(int型32位)
要注意的一点是: char一个字节的变量, 当按照%d打印,会将char隐式转为int型打印,转换过程中,高位的三个字节填充符号位的值.
%u 表示的是: 打印一个无符号的 十进制的整数(int型32位)
同理.%u打印会把参数转为unsigned int类型,再进行打印
问题1: 以下代码的运行结果是: -1 -1 255
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf( "a = %d, b = %d, c = %d", a, b, c);
char 型8位 -1 的补码是 1111 1111
int型32位 -1 的补码是 1111 1111 1111 1111 1111 1111 1111 1111
高位补的是符号位上的值,这是为了防止出现这样的转化过程中数据错误.
signed char 与 char 没有区别
unsigned char 在进行 %d打印时
1111 1111 高位补0(unsigned char 无符号位), 当做正数处理,补位按0补位.
则补位后结果是 0000 0000 0000 0000 0000 0000 1111 1111 ------> 255十进制数
结论: unsigned 类型变量比较坑, 容易在隐式转换等处发生问题, 能不用就不用unsigned.
问题2: 以下代码的运行结果是: 4,294,967,168
char a = -128;
printf("%u" , a);
思路: 把(char) a ---.> int----> unsigned int型打印
高位填充符号位 1000 0000
char ---> int \||/
1111 1111 1111 1111 1111 1111 1000 0000
int ---> unsigned int \||/
1111 1111 1111 1111 1111 1111 1000 0000 ||此时最高位不再是符号位, 不再表示负数,下面的数字就被理解为一个很大的正数4,294,967,168
问题3:以下代码的运行结果是:
char a = 128; // 128溢出 char 的范围是 -128 ---> +127
printf("%u \n", a);
128内存中二进制表示的是 0000 0000 0000 0000 0000 0000 1000 0000
char a = 128;发生截断,导致唯一的1变成了符号位,此时a的值本质为 -128;
\||/ 隐式转换为int
\||/ 转换为unsigned int 变成了很大的正数(回到问题2的过程中了)