文章目录
整形存放练习题
接上篇博客中未完结的整型练习题
上一篇博客我们展示了百度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 死循环打印
本章完!!
谢谢欣赏!!!!