C语言非常道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.1.1 标准整数类型

回到开头,继续讨论如何计算从1加到100。因为我们需要两个变量,一个存放初始数值“1”,另一个存放每次累加的结果,所以需要声明两个符号(标识符)。假定这两个符号分别是n和sum,则它们可以这样声明:

                int  n;
                int  sum;

问题是,尽管我们已经知道关键字“int”是C语言的类型指定符,代表的是一种整数类型,但它的数字表示范围是多少呢?这种类型的变量能容纳从1加到100的结果吗?

在C语言里内置了多种整数类型,它们有固定的名称,也明确地定义了最小的、可以保证的取值范围,称为标准整数类型。

我们已经知道,在计算机内部,整数的存储和运算有两套方法,一种是不考虑它们的符号,数字在存储时没有符号信息,所有比特都用来表示数字的大小;另一种则是将数字区分为正负,数字在存储时带有符号信息,要用1个比特来表示符号,其他剩余的比特才真正用于表示数字的大小。因为这个原因,标准整数类型又分为标准有符号整数类型和标准无符号整数类型。

在C语言里,标准有符号整数类型包括signed char、signed short int、signed int、signed long int和signed long long int。

在所有C语言可以适用的计算机上,signed char类型的变量要占用1个字节的存储空间。尽管“字节”的叫法很普遍,但它的比特长度却从来没有标准定义。对于C语言来说,一个字节至少要包含8个比特,不能再少了。所以,signed char类型可以表示的数据范围起码是-127有些基础的同学可能会问,为什么不是-128呢?事实上,C语言并未强制规定负数的表示方法,但现存的3种方案(对2的补码、对1的补码和符号带大小)在8位所能表示的负数范围上并不重合,只有对2的补码才有-128而其它两种只能表示到-127。在这种情况下,它就只能采取一个最小的、所有方案都能接受的数值-127。~+127,或者说是-(27-1)~+(27-1)。

之所以是2的7次方而不是8次方,是因为不包括符号位。另外,这里给出的只是最小范围,在有些机器上,1个字节被定义为具有9个或者更多的比特(这样的计算机可能很少,但不是没有),在这种机器上,signed char类型可表示的数据范围会比-127更小,比+127更大。

顾名思义,signed short int经常被叫作“短整型”,这个类型的名字也可以简单地写成signed short、short int或者直接写成short,该类型可以表示的数据范围起码是-32767~+32767,也即-(215-1)~+(215-1)。当然,这只是最低限度,取决于你的计算机,short类型可表示的数据范围可以比-32767更小,比+32767更大。

signed int可简单地写作int,或者直接写成signed,该类型可表示的数据范围起码是-32767~+32767,也即-(215-1)~+(215-1)。当然,这只是最低限度,取决于你的计算机,int类型可表示的数据范围可以比-32767更小,比+32767更大。

signed long int可简写为signed long、long int或者long,它可以表示的数据范围起码得是-2147483647~+2147483647,也即-(231-1)~+(231-1)。当然,这只是最低限度,取决于你的计算机,long类型可表示的数据范围可以比-2147483647更小,比+2147483647更大。

signed long long int可简写为signed long long、long long int或者直接写成long long,它可以表示的数据范围起码得是-9223372036854775807~+9223372036854775807,也即-(263-1)~+(263-1)。当然,这只是最低限度,取决于你的计算机,long long类型可表示的数据范围可以比-9223372036854775807更小,比+9223372036854775807更大。

你一定会问,为什么这些整数类型可以表示的数值范围不能固定下来,而仅仅是保证一个最基本的取值范围?这是因为不同的计算机系统具有不同的字长,C语言的发明者希望整数类型可以弹性地适应具体的计算机系统。比如说int类型,如果你还在用老旧的16位计算机,你只能用它来表示-32767~+32767之间的数值;如果你用的是32位计算机,它所表示的数据范围可扩大到-2147483647~+2147483647之间。在没有引入能表示更大整数的类型之前,这样做的好处是显而易见的。

如果仅仅是在同一种类型的计算机上编写、翻译和运行你的C语言程序,你完全可以无视标准的限制,自由使用计算机硬件和翻译器支持的取值范围。但是,你要想让自己的程序能够跑在不同的机器上,就必须遵守这个最低限制,必要时可以使用表示范围更大的其他整数类型。

既然有标准有符号整数类型,那自然也有标准无符号整数类型。在C语言里,标准无符号整数类型包括unsigned char、unsigned short int、unsigned int、unsigned long int和unsigned long long int,它们与相对应的有符号整数类型相比,占用的存储空间相同。所有无符号整数类型可表示的最小值是0,最大值因具体类型而异。

unsigned char类型可表示的最大值起码是255(28-1)。取决于字节的长度,可以比这个值更大。

unsigned short int可简写为unsigned short,该类型可表示的最大值起码是65535(216-1)。实际的取值范围可以比它更大,但不能再小。

unsigned int可简写为unsigned,该类型的最大值起码是65535(216-1),实际的取值范围可以比65535更大,但不能再小。

unsigned long int可简写为unsigned long,该类型的最大值起码是4294967295(232-1)。实际的取值范围可以比它更大,但不能再小。

unsigned long long int可简写为unsigned long long,该类型的最大值起码是18446744073709551615(264-1)。实际的取值范围可以比它更大,但不能再小。

标准无符号整数类型里还有一个_Bool,它是最近才引入的,以前没有,而且没有对应的有符号类型。它只能用来表示两个数字:0和1。

我们已经知道从1加到100的结果是5050,这个数值,除了_Bool、signed char和unsigned char,其他标准整数类型都足以表示。但是,为了讲解的连贯性,我们使用取值范围最宽的unsigned long long int类型来声明前面的n和sum:

                unsigned  long  long  int  n;
                unsigned  long  long  int  sum;

这样声明当然没有任何问题,但有点啰唆,毕竟C语言允许我们一次性声明多个符号,就像这样:

                unsigned  long  long  int  n,  sum;

很明显地,如果要一次性声明多个标识符,类型指定符出现一次即可,但各个标识符之间必须用逗号“,”分开。

练习1.1

1.C语言的标准整数类型包括哪两大类?这两大类又各自包括哪些具体的类型?

2.以下C语言的声明中,正确的是( )

A. char c;

B.signed char c

C.c:char;

D.c char;

3.当我们说“变量m”的时候,实际上说的是“标识符m所指示的变量”,对吗?若变量m的类型是signed long int,请写出它的声明。

4.在C语言中,“int”属于( )

A.类型指定符

B.关键字

C.所有声明的一部分

D.整数类型

5.在以下声明中,类型指定符是( );标识符是( );关键字是( );( )指示变量。

            int speed, width, height;

6.C语言中所指的变量可以位于( )

A.内存

B.寄存器

C.硬盘

D.U盘

7.变量是计算机存储器中的( )

A.存储区

B.数据

C.电信号

D.字节