这篇来简单说说C语言的数据类型中的整型.
1.整数与浮点数
这节内容在书中3.3章.
整数就是"没有小数部分的数",但是"一个值后面加上小数点,就变成了浮点数,概念与数学中的实数差不多"(43页).
举例来说, 2, 123456是整数,而2.0, 123456.789就是浮点数.
浮点数在运算,存储时可能会损失一定精度,比如"7.0可能被存储为6.999999",两个很大的数进行运算时,浮点数也会损失更多的精度.所以"浮点数通常都是接近实际值的近似值"(43-44页).
2.基本数据类型
这节内容在书中3.4章.
2.1 int
int类型不论在C还是Java还是其他编程语言中,应该都是最为常用的数据类型.
"一般而言,储存一个int要占用一个机器字长.(44页)".所以说早期的16位机器的int就是16位,范围很小.现在64位机器已经十分常见,所以可以存储更大的整数."ISO C规定int取值范围最小为-32768到32767(44页)".
1.定义并初始化int型变量
int number; //1 定义一个
int number1, number2, number3; //2 定义多个
int time = 60; //3 定义并初始化一个变量
int time1, time2 = 60; //4 有效,但是格式很糟糕(45页)
在4中,只初始化了time2,而time1并未被初始化.而这种写法会让人误以为time1,time2都被初始化了,所以不推荐这种写法.
2.不同进制下的整数
出了常用的十进制外,偶尔还会使用到八进制,十六进制.但是需要说明的是,无论使用哪种进制,"在计算机处理的过程中都以二进制的形式进行(46页)".
下面展示如何使用八进制十六进制输出一个十进制的值.
#include <stdio.h>
int main (void) {
int number = 254;
printf("十进制: %d, 八进制: %o, 十六进制: %x\n", number, number, number);
printf("十进制: %d, 八进制: %#o, 十六进制: %#x\n", number, number, number);//加一个#
return 0;
}
运行结果
十进制: 254, 八进制: 376, 十六进制: fe
十进制: 254, 八进制: 0376, 十六进制: 0xfe
加入一个#可以以0和0x形式输出八进制和十六进制数.
2.2 其他整数类型
如果有些场合不需要或不能够使用int,比如int类型的范围不够,这时就要使用其他类型了.
C语言提供了3个关键词修饰基本数据类型: short, long, unsigned.
下面列出的几种类型都可以省略最后面的int,比如long int可以简写为long(47页).
short int | 有符号类型,占用空间可能比int少 |
long int | 有符号类型,占用空间可能比int多 |
long long int | 有符号类型,占用空间可能比long int多 |
unsigned int | 无符号类型,C90新增 |
signed int | 强调是有符号类型 |
除此之外还有 unsigned short(C90), unsigned long int(C90), unsigned short int(C99), unsigned long long int(C99)类型,均可以省略最后面的int.
上面的表格中,有几行提到了可能.在Java中,占用的空间就是short(2byte) < int(4byte) < long(8byte),而在C语言中,情况发生了变化,因为在标准中,只规定了"short的存储空间不能多于int, long的存储空间不能少于int."(47页)
对于现在的计算机,常用设置是:"long long占用64位, long占32位, short占16位, int占16或32位."long long类型是为了满足64位机器的需求.下面的表格展示了各个类型表示的范围,后面的数字表示几位的机器,比如(32)就表示32位机器.
类型 | 最小值 | 最大值 |
short(16) | -32767 | 32767 |
int(16) | -32767 | 32767 |
long(32) | -2147483647 | 2147483647 |
unsigned short(32) | 0 | 65535 |
unsigned int(32) | 0 | 65535 |
unsigned long(32) | 0 | 4294967295 |
long long(64) | -9223372036854775807 | 9223372036854775807 |
unsigned long long(64) | 0 | 18446744073709551615 |
2.3输出
1.输出int值
#include <stdio.h>
int main (void) {
int number = 10; //初始化
int num; //未初始化
printf("已初始化的int变量:%d\n", number);
printf("未初始化的int变量:%d", num);
return 0;
}
运行结果
已初始化的int变量:10
未初始化的int变量:0
可以看到未初始化的变量也可以正常进行输出.
2.输出其他整型值
来看看如何输出short, long, long long, unsigned类型.
#include <stdio.h>
int main (void) {
short s = 1;
long l = 65537;
long long ll = 1234567890987654321;
unsigned int ui = 2345678900;
printf("short: hd = %hd, d = %d\n", s, s); //1
printf("long : ld = %ld, hd = %hd\n", l, l); //2
printf("long long: lld = %lld, ld = %ld\n", ll, ll);//3
printf("unsigned int: u = %u, d = %d\n", ui, ui); //4
}
运行结果
short: hd = 1, d = 1
long : ld = 65537, hd = 1
long long: lld = 1234567890987654321, ld = -1318314831
unsigned int: u = 2345678900, d = -1949288396
值得注意的是,如果使用了错误的转换,会产生难以理解的结果.
1行的结果是正确的,这里就不讨论了.这里出现了h修饰符,意思是"可以显示较大整数被截断成short类型值的情况"(50页),也就是后16位数字(二进制).short的后16位依旧是short,所以没有影响.
2中,使用了hd输出long值,就产生了影响.65537的二进制是0000000000000001(16位)0000000000000001(32位).由于h的存在,导致hd只输出了后16位,也就是0000000000000001,这个数转换成十进制就是1,就产生了这样的输出.
3中,ld表示只输出后32位,所以后面的值就是这个数的后32位表示的值.
4中,u代表无符号,可以输出原本的数字.而以d(有符号)的形式输出时,由于超出了有符号数的范围,且"这两个值在系统内存中的表示完全相同".(50页)而对于比较小的数字,两种方式的结果就都一样了,比如12345.