文章目录
- [ul]整形存放练习题
- 练习(一)
- 练习(二)
- 练习(三)
- 练习(四)
- 练习(五)
- 练习(六)
- 练习(七)
[/ul]
整形存放练习题
接上篇博客中未完结的整型练习题
上一篇博客我们展示了百度2015年系统工程师笔试题(不了解的看上一期博客—C语言进阶之数据的存储),请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。我们了解了大小端字节序存储的概念及方法,而今天这篇博客,我们将继续练习整型数据在内存中如何进行存放。
练习(一)
1.//输出什么?#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; }
请问最后的a,b,c打印的数字是多少?
分析:
char a = -1
10000000 00000000 00000000 00000001 —– -1的原码
11111111 11111111 11111111 11111110 —– -1的反码
11111111 11111111 11111111 11111111 —- -1的补码
(下次我们直接记住-1的补码为全1,当做常识)
1111111 —– -1在char中的存放
(由于是char类型的 ,存放一个字节,8个bit位)
11111111 11111111 11111111 11111111 —
打印的是%d,进行整形提升,得到内存中的补码
(不了解整形提升概念的,请关注往期的博客 — 隐性转换之整形提升)
打印的是原码,最后得到
10000000 00000000 00000000 00000001 —– -1的原码
结果还是 – 1
所以 a = -1
signed char 的打印结果和 char 的结果相同
得 b = -1
unsigned char c = -1
10000000 00000000 00000000 00000001 —– -1的原码
11111111 11111111 11111111 11111110 —– -1的反码
11111111 11111111 11111111 11111111 —- -1的补码
11111111
整形提升,高位补充0
00000000 00000000 00000000 11111111 – -1进行整形提升后的补码
由于是无符号数,原码、补码、反码相同,高位不算符号位。最后的结果就是
unsigned char c = 255
a = -1 , b = -1,c = 255
练习(二)
#include <stdio.h>int main(){char a = -128;printf(\"%u\\n\",a);return 0; }
练习三与练习二题目很接近,我们一起放上来
练习(三)
#include <stdio.h>int main(){char a = 128;printf(\"%u\\n\",a);return 0;}
在这两道题中,一个打印的是 a = -128的 % u,一个打印的是 a =128的%u
我们直接把 char 类型的二进制代表的数字总体介绍一下
有符号的char类型
无符号的char类型
%d 打印的是有符号整型
%u 打印的是无符号的整形
这一题打印的是 a = 128时 无符号的整型
我们知道,在正数里,char类型取不到128,那我们就将128看做是127+1,那么我们可以根据上面的 signed char 连续存放的环形图,得到我们存放 128 时,实际上在内存存放的是 -128,所以,练习(二)(三)打印的结果应该相同
10000000 00000000 00000000 10000000 — -128的原码
11111111 11111111 11111111 01111111 —- -128的反码
11111111 11111111 11111111 10000000 — -128的补码
无符号数,原码与补码相同,打印的结果是
练习(四)
#include <stdio.h>int main(){int i = -20;unsigned int j = 10;printf(\"%d\\n\", i + j);//按照补码的形式计划进行运算,最后格式转化成位有符号整数}
按照补码的形式计划进行运算,最后格式转化成位有符号整数
10000000 00000000 00000000 00010100 – -20的原码
11111111 11111111 11111111 11101011 – -20的反码
11111111 11111111 11111111 11101100 – -20的补码
00000000 00000000 00000000 00001010 –10的原码、反码、补码
11111111 11111111 11111111 11101100 – -20的补码
00000000 00000000 00000000 00001010 – 10的补码
补码相加
111111111 11111111 11111111 1110110 结果补码
111111111 11111111 11111111 1110101 结果反码
10000000 00000000 00000000 0001010 结果原码
对应的十进制数就为 -10
练习(五)
#include <stdio.h>int main(){unsigned int i;for (i = 9; i >= 0; i--){printf(\"%u\\n\", i);}}
i 是一个无符号数,永远大于0,所以,进入for语句会陷入死循环,减到0之后,-1在无符号数中,是全1,是一个很大的数字,之后陷入了持续减一的死循环。
练习(六)
#include <stdio.h>int main(){char a[1000];int i;for(i=0; i<1000; i++) {a[i] = -1-i; }printf(\"%d\",strlen(a));return 0; }
在 a [ i ]中放入
a [ 0 ] = -1
a [ 1 ] = -2
…
strlen函数遇到字符0或数值0停止
我们联想之前的char内存连续存放环形图可知道,存放的内容是
-1 -2 -3 -4 … -127 -128 127 126 125 … 3 2 1 0 // -1 -2 …以这样的循环存放1000个数
strlen数出的字节截止到0处,所以 128 + 127 = 255,所以结果为 255
练习(七)
#include <stdio.h>int main(){ unsigned char i = 0;for(i = 0;i<=255;i++) {printf(\"hello world\\n\"); }return 0;}
经过上面分析
unsigned char 的范围在 0——255之间,所以结果会显示为 hello world 死循环打印
本章完!!
谢谢欣赏!!!!