原文 from http://www.learncpp.com/cpp-tutorial/24-integers/
整型的变量如-1,0,3,4。C++中含有四种不同的整型变量,char,short,int和long。这些整型之间唯一的不同点是它们占有的内存大小,更大的整型能够保存更大的数值。你可以用sizeof操作符查看具体的大小。
在这个教程中,我们假设:
声明一些变量:
1: char chChar;
2: short int nShort; // "short int" is technically correct
3: short nShort2; // "short" is preferred shorthand
4: int nInteger;
5: long int nLong; // "long int" is technically correct
6: long nLong2; // "long" is preferred shorthand
虽然short int和long int是正确的用法,但是,我们更喜欢用简单的方式short 和 long 来代替它们。添加了int前缀使得类型更不好与int类型的变量进行区别。这回导致错误(如,溢出),如果带有short或long会不小心错过。(后两句话翻译的很别扭,大概是说将short int当成int,int当成了long int会发生溢出的错误)
因为char,short,int,long的大小取决于编译器或计算机架构,它能够通过整型的占用内存的大小来指出整型数值而不是名字。我们通常通过变量类型分配到的位或字节的数量来读取整型数值。
上一节中提到,分配到n位的变量能够是2^n不同的值。一个数据类型就具有它的取值范围。整型具有两种不同的范围,取决于它们是有符号的还是无符号的。
有符号和无符号变量
有符号整型能够存储正数和负数。声明变量是有符号的,你可以使用相应的关键词
1: signed char chChar;
2: signed short nShort;
3: signed int nInt;
4: signed long nLong;
一个字节的有符号整型的范围是-128到127.任何一个在-128到127(包括)内的数字都能安全的放到一个字节中。
有时,我们事先知道我们不会使用负数。这样通常使用unsigned整型。
1: unsigned char chChar;
2: unsigned short nShort;
3: unsigned int nInt;
4: unsigned long nLong;
一个字节的无符号整型变量的范围在0到255.
将变量声明为无符号整型,说明变量不能用来存储负数,但是能够存储更大的整数。
如果我们没有将变量声明为signed或者是unsigned?所有的变量除了char都是默认为signed的。char可能默认成signed或是unsigned,不过通常是signed。
1: short nShort; // signed by default
2: int nInt; // signed by default
3: long nLong; // signed by default
4: char chChar; // can be signed or unsigned by default, but probably signed.
对于新手,经常会将unsigned和signed搞混。下面是一个简单的方法来记住它们之间的区别:为了区分正负数,我们通常使用负号。如果一个标记没有提供,我们认为是正数。因此,一个带符号的整数可以区分正和负数。一个整数没有符号,被认为都是正数。
Size/Type | Range |
---|---|
1 byte signed | -128 to 127 |
1 byte unsigned | 0 to 255 |
2 byte signed | -32,768 to 32,767 |
2 byte unsigned | 0 to 65,535 |
4 byte signed | -2,147,483,648 to 2,147,483,647 |
4 byte unsigned | 0 to 4,294,967,296 |
8 byte signed | -9,223,372,036,854,775,807 to 9,223,372,036,854,775,807 |
8 byte unsigned | 0 to 18,446,744,073,709,551,615 |
从数学上来讲,n位符号变量的范围在-(2^(n-1))到(2^(n-1))-1。n位无符号变量范围在(2^n)-1。
如果把大范围的数据放入到小范围的类型中呢?
溢出
用二进制表示,从0到15为:0, 1, 10, 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011, 1101, 1111.正如你所见的,数值越大,需要更多的位来存储。因为我们的变量都具有一定的位数,它限制了能够存储的最大的数值。
假设一个变量分配到4位。上面的所有的数字都能够存储到这个变量中。但是当我们将5位的数值赋值到你的变量时会发生什么呢?溢出就发生了,超出4位的部分就会丢失。
溢出在当一个变量的存储空间不够时发生丢失的现象。
我们来查看一下下面的代码:
1: #include <iostream>
2:
3: int main()
4: {
5: using namespace std;
6: unsigned short x = 65535; // largest 2-byte unsigned value possible
7: cout << "x was: " << x << endl;
8: x = x + 1; // We desire 65536, but we get overflow!
9: cout << "x is now: " << x << endl;
10: }
得到如下的结果:
x was: 65535 x is now: 0
同样当我们在底部溢出时:
1: #include <iostream>
2:
3: int main()
4: {
5: using namespace std;
6: unsigned short x = 0; // smallest 2-byte unsigned value possible
7: cout << "x was: " << x << endl;
8: x = x - 1; // We expect -1, we get overflow!
9: cout << "x is now: " << x << endl;
10: }
结果如下:
x was: 0 x is now: 65535
对于符号整型也具有类似的现象:
1: #include <iostream>
2:
3: int main()
4: {
5: using namespace std;
6: signed short x = 32767; // largest 2-byte signed value possible
7: cout << "x was: " << x << endl;
8: x = x + 1; // We desire 32768, but we get overflow!
9: cout << "x is now: " << x << endl;
10: }
结果是什么呢??
整数位数的修正
一些编译器对整数的位数提供了修正。由于它不是标准C++的一部分,我们将它放在了附录A.6-fixed width integers中。不过还是建议读一下。