目录:简单变量(二)
- 一、无符号类型
- 二、选择整型类型
- 三、 char类型:字符和小整数
一、无符号类型
前面介绍的4种整型都有一种不能存储负数值的无符号变体,其优点是可以增大变量能够存储的最大值。
例如,如果short表示的范围为−32768到+32767,则无符号版本的表示范围为0-65535。
当然,仅当数值不会为负时才应使用无符号类型,如人口、粒数等。要创建无符号版本的基本整型,只需使用关键字unsigned来修改声明即可:
下面的程序演示了如何使用无符号类型,并说明了程序试图超越整型的限制时将产生的后果。最后,再看一看预处理器语句#define。
程序如下所示:
#include <iostream>
#define ZERO 0
#include <climits>
int main() {
using namespace std;
short sam = SHRT_MAX;
unsigned short sue = sam;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars desposit" << endl;
cout << "Add 10 dollars to each account" << endl << "Now ";
sam = sam + 1;
sue = sue + 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars desposit" << endl;
sam = ZERO;
sue = ZERO;
cout << "Sam has " << sam << " dollars and Sue has " << sue << endl;
sam = sam - 1;
sue = sue - 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue << " dollars" << endl;
return 0;
}
输出结果为:
Sam has 32767 dollars and Sue has 32767 dollars desposit
Add 10 dollars to each account
Now Sam has -32768 dollars and Sue has 32768 dollars desposit
Sam has 0 dollars and Sue has 0
Sam has -1 dollars and Sue has 65535 dollars
D:\C++Project\demo\x64\Debug\demo.exe (进程 59664)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
该程序将一个short变量(sam)和一个unsigned short变量(sue)分别设置为最大的short值,在我们的系统上,是32767。然后将这些变量的值都加1。这对于sue来说没什么问题,因为新值仍比无符号整数的最大值小得多;但sam的值从32767变成了−32768!同样,对于sam,将其设置为0并减去1,也不会有问题;但对于无符号变量sue,将其设置为0并减去后,它变成了65535。
可以看出,这些整型变量的行为就像里程表。如果超越了限制,其值将为范围另一端的取值。C++确保了无符号类型的这种行为;但C++并不保证符号整型超
越限制(上溢和下溢)时不出错,而这正是当前实现中最为常见的行为。
我们看一下典型的整型溢出行为:
二、选择整型类型
C++提供了大量的整型,应使用哪种类型呢?
通常,int被设置为对目标计算机而言最为“自然”的长度。自然长度(natural size)指的是计算机处理起来效率最高的长度。如果没有非常有说服力的理由来选择其他类型,则应使用int。
现在来看看可能使用其他类型的原因。如果变量表示的值不可能为负,如文档中的字数,则可以使用无符号类型,这样变量可以表示更大的值。
如果知道变量可能表示的整数值大于16位整数的最大可能值,则使用long。即使系统上int为32位,也应这样做。这样,将程序移植到16位系统时,就不会突然无法正常工作(如下图)。如果要存储的值超过20亿,可使用long long。
如果short比int小,则使用short可以节省内存。通常,仅当有大型整型数组时,才有必要使用short。(数组是一种数据结构,在内存中连续存储同类型的多个值。)如果节省内存很重要,则应使用short而不是使用int,即使它们的长度是一样的。例如,假设要将程序从int为16位的系统移到int为32位的系统,则用于存储int数组的内存量将加倍,但short数组不受影响。请记住,节省一点就是赢得一点。
如果只需要一个字节,可使用char,这将稍后介绍。
三、 char类型:字符和小整数
下面介绍最后一种整型:char类型。顾名思义,char类型是专为存储字符(如字母和数字)而设计的。现在,存储数字对于计算机来说算不了什么,但存储字母则是另一回事。编程语言通过使用字母的数值编码解决了这个问题。因此,char类型是另一种整型。它足够长,能够表示目标计算机系统中的所有基本符号—所有的字母、数字、标点符号等。实际上,很多系统支持的字符都不超过128个,因此用一个字节就可以表示所有的符号。因此,虽然char最常被用来处理字符,但也可以将它用做比short更小的整型。
下面的程序使用了char类型。
#include <iostream>
int main() {
using namespace std;
char cn;
cout << "请输入一个字符串: " << endl;
cin >> cn;
cout << "thank you for " << cn;
return 0;
}
输出结果为:
请输入一个字符串:
M
thank you for M
D:\C++Project\demo\x64\Debug\demo.exe (进程 43504)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
有趣的是,程序中输入的是M,而不是对应的字符编码77。
另外,程序将打印M,而不是77。通过查看内存可以知道,77是存储在变量ch
中的值。
这种神奇的力量不是来自char类型,而是来自cin和cout,这些工具为您完成了转换工作。输入时,cin将键盘输入的M转换为77;输出时,cout将值77转换为所显示的字符M;cin和cout的行为都是由变量类型引导的。
如果将77存储在int变量中,则cout将把它显示为77(也就是说,cout显示两个字符7)。
下面的程序说明了一点,该程序还演示了如何在C++中书写字符字面值:将字符用单引号括起,如’M’(注意,示例中没有使用双引号。C++对字符用单引号,对字符串使用双引号。cout对象能够处理这两种情况,但正如第4章将讨论的,这两者有天壤之别)。最后,程序引入了cout的一项特性—cout.put( )函数,该函数显示一个字符。
代码为:
#include <iostream>
int main() {
using namespace std;
char cn = 'M';
int i = cn;
cout << "The ASCII code for " << cn << " is " << i << endl;
cout << "Add one character code: " << endl;
cn = cn + 1;
i = cn;
cout << "The ASCII code for " << cn << " is " << i << endl;
cout << "Displaying char cn using cout.put(cn): ";
cout.put(cn);
cout.put('!');
cout << endl << "Done!" << endl;
return 0;
}
输出结果为:
The ASCII code for M is 77
Add one character code:
The ASCII code for N is 78
Displaying char cn using cout.put(cn): N!
Done!
D:\C++Project\demo\x64\Debug\demo.exe (进程 62944)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
程序说明:
‘M’表示字符M的数值编码,因此将char变量cn初始化为‘M’,将把cn设置为77。然后,程序将同样的值赋给int变量i,这样cn和i的值都是77。接下来,cout把cn显示为M,而把i显示为77。如前所述,值的类型将引导cout选择如何显示值—这是智能对象的另一个例子。
由于cn实际上是一个整数,因此可以对它使用整数操作,如加1,这将把cn的值变为78。然后,程序将i重新设置为新的值(也可以将i加1)。cout再次将这个值的char版本显示为字符,将int版本显示为数字。
C++将字符表示为整数提供了方便,使得操纵字符值很容易。不必使用笨重的转换函数在字符和ASCII码之间来回转换。
即使通过键盘输入的数字也被视为字符。请看下面的代码:
如果您输入5并按回车键,上述代码将读取字符“5”,并将其对应的字符编码(ASCII编码53)存储到变量cn中。请看下面的代码:
如果您也输入5并按回车键,上述代码将读取字符“5”,将其转换为相应的数字值5,并存储到变量n中。
最后,该程序使用函数cout.put( )显示变量cn和一个字符常量。
成员函数cout.put( )
:
cout.put( )到底是什么东西?其名称中为何有一个句点?函数cout.put( )是一个重要的C++ OOP概念—成员函数—的第一个例子。类定义了如何表示和控制数据。成员函数归类所有,描述了操纵类数据的方法。例如类ostream有一个put( )成员函数,用来输出字符。只能通过类的特定对象(例如这里的cout对象)来使用成员函数。要通过对象(如cout)使用成员函数,必须用句点将对象名和函数名称(put( ))连接起来。句点被称为成员运算符。cout.put( )的意思是,通过类对象cout来使用函数put( )。第10章介绍类时将更详细地介绍这一点。现在,您接触的类只有istream和ostream,可以通过使用它们的成员函数来熟悉这一概念。
cout.put( )成员函数提供了另一种显示字符的方法,可以替代<<运算符。