Learning C++ 之 2.4 整数

整数类型变量是不包含分数的变量,如(-2,-1,0,1,2),C++有5种不同类型的整形变量可供使用:

CategoryTypeMinimum SizeNote
characterchar1 byte 
integershort2 bytes 
 int2 bytesTypically 4 bytes on modern architectures
 long4 bytes 
 long long8 bytesC99/C++11 type

Char类型是一种比较特殊的类型,它可以同时作为整形和字符型使用,这个后面会详细讨论,本章中你只需要把它当成一个简单的整形就OK了。

上面的几种整形的不同之处就是size的不同,size越大,可存储的数据值也就越大。需要注意的是C++只是规定了整形变量的最小size,并不是特定的size,可以参照上一节内容。因此各种不同类型在你的机器上size可能是不同的。

定义整型数据类型:

定义一些整数:

char c;
short int si; // valid
short s;      // preferred
int i;
long int li; // valid
long l;      // preferred
long long int lli; // valid
long long ll;      // preferred

虽然short int,long int,long long int的定义符是有效的,但是建议优先使用short,long,long long的定义方式。除了写起来更加简单之外,这样还会使这些变量与int类型可以比较好的区分开,同时如果无心漏写了long,short,我们会及时发现数据类型定义错误。

识别整型:

因为整型的size跟编译环境以及硬件电脑相关,那么使用变量,而不是名字来定义整型更加有效,如我们经常通过分配给变量的位数来识别整型类型,如32 bit数据替代long。

整型的范围和标志:

根据上一节的内容来看,n位size可以表示2的n次方个不同数据。但是这些是什么数据呢?我们称这系列特殊的数据教过整型的范围。整型的类型由两方面决定:1.size  2.符号(通常分为有符号和无符号数据)

signed标志该数据可以包含正数和负数两种类型,如下:

signed char c;
signed short s;
signed int i;
signed long l;
signed long long ll;

惯例来说,一般不会在前面写上signed类型。

1 byte size(8位)可以表示signed的数值是-127~128范围的数据。

有些时候我们并不需要负数,这样就需要unsigned的类型。比如需要存储size的大小,你的身高,体重不可能用复数。此时我们就可以使用unsigned的数值表示。

unsigned char c;
unsigned short s;
unsigned int i;
unsigned long l;
unsigned long long ll;

1 byte size可以存储的unsigned的数值是0~255范围的数据

可以看出来,无符号的数值,同等size下不能保存负数,但是正数的范围会扩大一倍。

既然你已经了解了signed和unsigned的不同,就请参考一下下面的数据范围:

Size/TypeRange
1 byte signed-128 to 127
1 byte unsigned0 to 255
2 byte signed-32,768 to 32,767
2 byte unsigned0 to 65,535
4 byte signed-2,147,483,648 to 2,147,483,647
4 byte unsigned0 to 4,294,967,295
8 byte signed-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
8 byte unsigned0 to 18,446,744,073,709,551,615

对于数值来说,一般n位的size可以保存的signed数值的范围是:-(2的n-1次方)~ (2的n-1次方)-1;unsigned数值的方位就是2的n次方-1.

新手往往会把sign和unsign搞混。其实比较好区分,在需要区分正负的场合,我们就需要使用有符号的声明。而在只有正数的需求的时候,我们会使用unsigned的数据类型。

使用方法:

当你没有特别声明是否是有符号时:

CategoryTypeDefault SignNote
charactercharSigned or UnsignedUsually signed
integershortSigned 
 intSigned 
 longSigned 
 long longSigned

所有的数据类型都被默认为signed,char类型可以是signed或者unsigned,默认是signed。

通常来说signed字符是冗余不需要的,因为默认就是signed。

最好的使用方法就是除非由unsiged的需求,否则不需要定义unsigned变量。因为无符号变量可能会引起一些bug。

规则:优先选择有符号的整数类型

溢出:

当我们把一个数据类型范围之外的整数放到变量中,会发生什么情况呢?这个时候会产生溢出的问题,因为变量没有足够的空间来存储该变量。在2.1节中,我们提到了变量是以二进制存储的。

二进制数据中每一位都有两种可能,如下加入我们想要从0数到15,那么如下表所示:

Decimal ValueBinary Value
00
11
210
311
4100
5101
6110
7111
81000
91001
101010
111011
121100
131101
141110
151111

你可以看到越大的数会有越大的位数来存储,因为我们的变量需要固定的位数来表示,这就限制了他们能保存多大的数据。

溢出的例子:

假设一个无符号的变量只能容纳4位,上面表中每个数据都足以编导这个变量中。

但是假如我们想把一个超过4位的变量放到这个变量里会发生什么事情呢?这个时候就会溢出,变量只存储了右边4位,而不是完全存储。

比如我们想要把21放到4位的变量里:

Decimal ValueBinary Value
2110101

这个时候我们只会得到0101,最前面的一位1就不见了。也就是存储了5这个数字。

在本章你不需要直到二进制和十进制怎么转换,我们在后面的3.7章节会详细讨论。

下面让我们以实际例子来看看数据溢出的问题,假设short类型时16位:

#include <iostream>
 
int main()
{
    unsigned short x = 65535; // largest 16-bit unsigned value possible
    std::cout << "x was: " << x << std::endl;
    x = x + 1; // 65536 is out of our range -- we get overflow because x can't hold 17 bits
    std::cout << "x is now: " << x << std::endl;
    return 0;
}

你觉的结果应该是什么?

x was: 65535
x is now: 0

发生了什么?我们想把65536放到一个16位的变量中,但是65536二进制是17位的,10000000000000000,这个时候取右边16位,自然就是0了。

溢出导致了信息的丢失,这是非常不可取的。所以假如你要存储一个很大的变量,一定要尽可能大的使用相应的变量类型。

溢出结果只针对无符号整数,有符号的整数或者小数溢出后会有不同的结果,这个会根据不同的系统的情况而不同。

整数的除法:

当整数可以整除的时候,那么程序输出的结果和你预想的是一样的:

#include <iostream>
 
int main()
{
    std::cout << 20 / 4;
    return 0;
}

该程序会输出5.

但是当除法不能整除的时候看看:

#include <iostream>
 
int main()
{
    std::cout << 8 / 5;
    return 0;
}

这个程序的输出结果是:1

当两个整数做除法的时候,C++只能生成一个整数的结果,也就把小数部分直接丢掉了。如例子中8/5=1.6,但是程序算出来就是1,0.6直接丢掉。

小心使用整数的除法,因为会丢掉小数部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值