在c语言中,不同类型的数据在内存中基本上没有差异,那么这些定义的类型的作用是啥呢?这些定义的类型是来改变编译器对这些数据提取时的方式,下面让我们来看一些经典例题!!
#include<stdio.h>
#include<Windows.h>
int main()
{
unsigned int i;
for (i = 9; i >= 0; i--) //i永远为正嘛,肯定会死循环
{
printf("%u\n", i);
Sleep(1000);
}
return 0;
}
这里的i是一个无符号整形定义的数;
从循环大体来看,因为i为无符号整形,所以无论如何i的值都恒为正(先不管它为多少),所以这里肯定是一个死循环;
(sleep函数是让待会的结果暂留,便于观察输出的哪些数)
很轻松可知,在i从9到0会正常输出 9、8、7、6、5.......2、1、0
当减为零的时候,下一个将会输出什么呢,我们来分析一下:
0在内存中为(补码):00000000 00000000 00000000 00000000
-1在内存中为(补码): 11111111 11111111 11111111 11111111
做和 : 11111111 11111111 11111111 11111111
此时输出这个数,由于是按%u(无符号)输出,所以编译器直接把这个数转成十进制输出(不管它的最高位);
11111111 11111111 11111111 11111111转成十进制为:4294967295
然后又按照这个数每次减一.......
例二 :
#include<stdio.h>
#include<string.h>
int main()
{
char a[1000];
int i;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d\n", strlen(a));
return 0;
}
char类型的取值范围为:-128~127
所以按照这样减下去,当i等于127时,下一个就会开始超出范围溢出
当i=255时,a[255] = -256 ; -256在内存中为(补码):1 0000 0000 (这种类型的要记住,有规律) (例:-128:1000 0000)
又因为为char类型(八个比特位),所以在内存中存储该数据时要发生截断(多了一个比特位),截断后为: 0000 0000
此处截断了最高位(符号位)
所以a[255] = 0; strlen函数遇到0就会截止(不计入0那一个),所以答案为255;
(注意:‘\0’的ASCII值就是0)
运行结果:
例三:(注释把原因写得很清楚)
#include<stdio.h>
#include<math.h>
int main()
{
short num = 32767; // num的补码: 01111111 11111111
short int a = num + 1; //a的补码: 10000000 00000000
printf("%d\n", a); //因为按%d输出,所以先整形提升
//整形提升后:11111111 11111111 10000000 00000000(补码)
// 11111111 11111111 01111111 11111111(反码)
// 10000000 00000000 10000000 00000000 (-32768)输出结果:-32768
return 0;
}