前言
书接上回,我们学习了整形数据在内存中是怎么存储的。本篇我们就利用这些知识来做一些练习题目,把这些知识很好的消化掉。
知识补充
对于整形家族的类型来说,有:无符号和有符号的区分。
unsigned : 表示“无符号”
signed:表示:“有符号”
我们平常所说的int等价于signed。
注:char到底是unsigned还是signed是不确的,char在vs上是signed。
有符号和无符号的区别
用char举例,看图
一个小知识:有符号char的取值范围是 -128~127,
无符号的取值范围是 0~255
看图可以更好的理解
用这种方法任何类型都可以计算了
其实我们是可以发现一个小规律的,无符号char中,255+1,又跳到0去了,形成了一个轮回,用一个圆圈来表示:
我们可以看见,无符号位的char的127+1变成了128,而有符号位的char中的127+1变成了-128.并且无符号位中的255加1又回到了0,所以无符号char能存储的最大数就是255.超过255又会重新回到0.
练习一
这个代码的运行结果
#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=-1,b=-1,c=255
解析
b是signed char 等价于 char,他们两个的执行结果会一样
练习二
这代码的运行结果
#include <stdio.h> int main() { char a = -128; printf("%u\n",a); return 0; }
答案
4294967168
解析
感兴趣的小伙伴可以用计算器去算一下
练习三
这个代码的运行结果
#include <stdio.h> int main() { char a = 128; printf("%u\n", a); return 0; }
答案
4294967168
解析
练习四
这个代码的运行结果
int i= -20; unsigned int j = 10; printf("%d\n", i+j);
答案
-10
我做这个题目的时候也是进行了很强的思想斗争的,老老实实算了一次之后没想到就是-10
解析
练习五
运行结果
unsigned int i; for(i = 9; i >= 0; i--) { printf("%u\n",i); }
答案
死循环
解析
这里的变量 i 是无符号整型,一个无符号数是肯定不会是负数的,当 i 等于0时再减去1,它会像我们刚刚讨论的无符号char类型一样变成无符号整型中的最大值,而不是-1,所以它会一直打印下去
练习六
运行结果
int main() { char a[1000]; int i; for(i=0; i<1000; i++) { a[i] = -1-i; } printf("%d",strlen(a)); return 0; }
这里数组a的长度为255,我们来分析这一点.首先,数组a中存储的数据是有符号char类型的数据,数据范围是: -128 ~ 127之间.这里循环中 i 的范围是: -1 ~ -999 之间,数组中的内容会从-1开始一直往后存储,当i等于-128时,-1-128这时根据我们上面画的循环图,-1-128就等于127.下一步-1-129同理也就是等于126,然后125,124…这样存储下去,直到它变为0后又减一变成-1,以此循环往复直到装满1000个数为止.
当我们分析到这里还没有结束,我们知道这1000个元素其实就是 -128~127之间所有的数重复了几遍组成的,然而我们知道 strlen操作符的结束标志是遇见’\0’, 并且’\0’的ASCLL值是0,也就是说当strlen遇见0时,它就会终止,在外面数组中遇见的第一个0就会被系统当作数组的长度,根据外面刚才的分析,可以得出,第一个0出现时有128+127=255个元素已经在数组中,所以系统会认为数组的长度为255.也就是打印255.
练习七
运行结果
#include <stdio.h> unsigned char i = 0; int main() { for(i = 0;i<=255;i++) { printf("hello world\n"); } return 0; }
这个代码也会死循环打印hello world,这是因为当循环走到 i 等于255时, i 再加一其实不是256,因为无符号char类型能够存储的最大数就是255,根据外面刚刚画的循环图,255加一后就会重新走到0,以此一直循环下去.
下期预告:讲解浮点型数据在内存中的存储