文章目录
- 前言
- 一、简单变量
- 1. 变量名
- 2. 整型
- 2.1 整型类型
- 2.2 无符号类型
- 2.3 char 类型
- 2.4 signed char 和unsigned char
- 2.5 bool类型
- 3.浮点数
- 4.类型转换
- 总结
前言
该系列文章请点击专栏查看
一、简单变量
1. 变量名
C++提倡使用有一定含义的变量名,必须遵循几种简单的C++命名规则。
- 在名称中只能使用字母字符、数字和下划线_。
- 名称的第一个字符不能是数字。
- 区分大写字符与小写字符。
- 不能将 C++关键字用作名称。
- 以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符。
- C++对于名称的长度没有限制,名称中所有的字符都有意义,但有些平台有长度限制。
倒数第二点与前面几点有些不同,因为使用像timestop或 Donut 这样的名称不会导致编译器错误,而会导致行为的不确定性。换句话说,不知道结果将是什么。不出现编译器错误的原因是,这样的名称不是非法的,但要留给实现使用。全局名称指的是名称被声明的位置,这将在第4章讨论。最后一点使得C++与 ANSIC(C99标准)有所区别,后者只保证名称中的前63个字符有意义(在ANSIC中,前63个字符相同的名称被认为是相同的,即使第64个字符不同)。
2. 整型
整数就是没有小数部分的数字,如2、98、-5286和0。整数有很多,如果将无限大的整数看作很大,则不可能用有限的计算机内存来表示所有的整数。因此,语言只能表示所有整数的一个子集。有些语言只提供一种整型(一种类型满足所有要求!),而 C++则提供好几种,这样便能够根据程序的具体要求选择最合适的整型。
不同 C++整型使用不同的内存量来存储整数。使用的内存量越大,可以表示的整数值范围也越大。 另外,有的类型(符号类型)可表示正值和负值,而有的类型(无符号类型)不能表示负值。术语宽度(width)用于描述存储整数时使用的内存量。使用的内存越多,则越宽。C++的基本整型(按宽度递增的顺序排列)分别是char、short、int、long和 C++11新增的longlong,其中每种类型都有符号版本和无符号版本,因此总共有 10种类型可供选择。由于char类型有一些特殊属性(它最常用来表示字符,而不是数字),因此将首先介绍其他类型。
2.1 整型类型
- short 至少16位;
- int 至少与 short 一样长;
- long 至少 32 位,且至少与int 一样长;
- long long 至少 64 位,且至少与 long 一样长。
头文件 climits 定义了符号常量来表示类型的限制。INTMAX表示类型int能够存储的最大值,对于 Windows7系统,为2147483 647。编译器厂商提供了 climits 文件,该文件指出了其编译器中的值。例如,在使用16位int的老系统中,climits 文件将 INT MAX定义为 32 767。下表对该文件中定义的符号常量进行了总结,其中的一些符号常量与还没有介绍过的类型相关。
2.2 无符号类型
前面介绍的4种整型都有一种不能存储负数值的无符号变体,其优点是可以增大变量能够存储的最大值。例如,如果short 表示的范围为-32768 到+32767,则无符号版本的表示范围为 0-65535。当然,仅当数值不会为负时才应使用无符号类型,如人口、粒数等。要创建无符号版本的基本整型,只需使用关键字unsigned
来修改声明即可:
using namespace std;
short sam=SHRT_MAX;//initialize a variable to max value
unsigned short sue= sam;//okay if variable sam already defined
cout<<"Sam has"<<sam<<"dollars and Sue has "<< sue;cout<<"dollars deposited."<<endl;
<< "Add $l to each account."<< endl << "Now ";
sam = sam +1;
sue = sue +1;
cout << "Sam has "<<sam <<" dollars and Sue has "<< sue;
cout<<"dollars deposited.nPoor Sam!"<< endl;
sam = 0;
sue = 0;
cout <<"Sam has "<< sam <<" dollars and Sue has " << sue;
cout<<"dollars deposited."<< endl;
cout <<"Take $l from each account." << endl << "Now ";
sam =sam-1;
sue =sue-1;
cout <<"Sam has "<< sam<<"dollars and Sue has " << sue;cout <<" dollars deposited." << endl << "Lucky Sue!" << endl;
return 0;
运行后输出如下:
该程序将一个short 变量(sam)和一个 unsigned short 变量(sue)分别设置为最大的short 值,在我们的系统上,是 32767。然后,将这些变量的值都加1。这对于sue 来说没有什么问题,因为新值仍比无符号整数的最大值小得多;但 sam的值从32767变成了-32768!同样,对于sam,将其设置为0并减去1,也不会有问题;但对于无符号变量sue,将其设置为0并减去后,它变成了65535。可以看出,这些整型变量的行为就像里程表。如果超越了限制,其值将为范围另一端的取值(参见图 3.1)。C++确保了无符号类型的这种行为:但C++并不保证符号整型超越限制(上溢和下溢)时不出错,而这正是当前实现中最为常见的行为。
2.3 char 类型
char类型是专为存储字符(如字母和数字)而设计的。现在,存储数字对于计算机来说算不了什么,但存储字母则是另一回事。编程语言通过使用字母的数值编码解决了这个问题。因此,char 类型是另一种整型。它足够长,能够表示目标计算机系统中的所有基本符号–所有的字母、数字、标点符号等。实际上,很多系统支持的字符都不超过128个,因此用一个字节就可以表示所有的符号。因此,虽然char最常被用来处理字符,但也可以将它用做比short更小的整型。
在C++中,书写字符常量的方式有多种。对于常规字符(如字母、标点符号和数字),最简单的方法是将字符用单引号括起。这种表示法代表的是字符的数值编码。例如,ASCII系统中的对应情况如下:
- 'A’为65,即字符A的 ASCII码;
- 'a’为 97,即字符a的 ASCII码;
- '5’为53,即数字5的 ASCI码;
- ‘!’为33,即感叹号的 ASCII码。
这种表示法优于数值编码,它更加清晰,且不需要知道编码方式。如果系统使用的是EBCDIC,则A的编码将不是 65,但是’A’表示的仍然是字符 A。有些字符不能直接通过键盘输入到程序中。例如,按回车键并不能使字符串包含一个换行符;相反,程序编辑器将把这种键击解释为在源代码中开始新的一行。其他一些字符也无法从键盘输入,因为 C++语言赋予了它们特殊的含义。例如,双引号字符用来分隔字符串字面值,因此不能把双引号放在字符串字面值中。对于这些字符,C++提供了一种特殊的表示方法——转义序列。例如,\n表示换行符,\”将双引号作为常规字符,而不是字符串分隔符。可以在字符串或字符常量中使用这些表示法,如下例所示:
2.4 signed char 和unsigned char
与int不同的是,char 在默认情况下既不是没有符号,也不是有符号。是否有符号由C++实现决定,这样编译器开发人员可以最大限度地将这种类型与硬件属性匹配起来。如果 char 有某种特定的行为对您来说非常重要,则可以显式地将类型设置为signed char或unsigned char:
char fodo; //may be signed,may be unsigned
unsigned char bar;//definitely unsigned
signed char snark;// definitely signed
如果将 char 用作数值类型,则 unsigned char 和 signed char之间的差异将非常重要。unsigned char 类型的表示范围通常为 0~255,而 signed char 的表示范围为-128 到127。例如,假设要使用一个 char 变量来存储像 200这样大的值,则在某些系统上可以,而在另一些系统上可能不可以。但使用 unsigned char 可以在任何系统上达到这种目的。另一方面,如果使用char变量来存储标准ASCII 字符,则char 有没有符号都没关系,在这种情况下,可以使用char。
2.5 bool类型
bool变量的值是false或true,C++将非零值解释为true,将零解释为false,也可以理解为真或假。
3.浮点数
浮点数能够表示带小数部分的数字,提供的值范围也更大。
C++有3种浮点类型:float、double和long double。这些类型是按它们可以表示的有效数位和允许的指数最小范围来描述的。有效位(significant figure)是数字中有意义的位。例如,加利福尼亚的 Shasta山脉的高度为14179英尺,该数字使用了5个有效位,指出了最接近的英尺数。然而,将Shasta山脉的高度写成约14000英尺时,有效位数为2位,因为结果经过四舍五入精确到了千位。在这种情况下,其余的3位只不过是占位符而已。有效位数不依赖于小数点的位置。例如,可以将高度写成 14.162千英尺。这样仍有5个有效位,因为这个值精确到了第5位。事实上,C和C++对于有效位数的要求是,float至少32位,double至少48位,且不少于float,long double至少和 double 一样多。这三种类型的有效位数可以一样多。然而,通常,foat为32位,double为64位,long double为80、96或128位。另外,这3种类型的指数范围至少是-37到37。
以上表示浮点值的方法叫做E表示法,其外观是像这样的: 3.45E6,这指的是3.45与1000000相乘的结果;E6指的是10的6次方,即1后面6个0。因此,3.45E6表示的是3450000,6被称为指数,3.45被称为尾数。
记住:d.dddE+n指的是将小数点向右移n位,而d.dddE-n指的是将小数点向左移n位。之所以称为“浮点”,就是因为小数点可移动。
与整数相比,浮点数有两大优点。首先,它们可以表示整数之间的值。其次,由于有缩放因子,它们可以表示的范围大得多。另一方面,浮点运算的速度通常比整数运算慢,且精度将降低。
4.类型转换
C++丰富的类型允许根据需求选择不同的类型,这也使计算机的操作更复杂。例如,将两个 shont 值相加涉及到的硬件编译指令可能会与将两个long值相加不同。由于有11种整型和3种浮点类型,因此计算机需要处理大量不同的情况,尤其是对不同的类型进行运算时。为处理这种潜在的混乱,C++自动执行很多类型转换:
- 将一种算术类型的值赋给另一种算术类型的变量时,C++将对值进行转换;
- 表达式中包含不同的类型时,C++将对值进行转换;
- 将参数传递给函数时,C+将对值进行转换。
具体在表达式中进行数值转换:
(1)如果有一个操作数的类型是long double,则将另一个操作数转换为 long double。
(2)否则,如果有一个操作数的类型是double,则将另一个操作数转换为 double。
(3)否则,如果有一个操作数的类型是foat,则将另一个操作数转换为 foat。
(4)否则,说明操作数都是整型,因此执行整型提升。
(5)在这种情况下,如果两个操作数都是有符号或无符号的,且其中一个操作数的级别比另一个低,则转换为级别高的类型。
(6)如果一个操作数为有符号的,另一个操作数为无符号的,且无符号操作数的级别比有符号操作数高,则将有符号操作数转换为无符号操作数所属的类型。
(7)否则,如果有符号类型可表示无符号类型的所有可能取值,则将无符号操作数转换为有符号操作数所属的类型。
(8)否则,将两个操作数都转换为有符号类型的无符号版本。
总结
C++的基本类型分为两组:一组由存储为整数的值组成,另一组由存储为浮点格式的值组成。整型之间通过存储值时使用的内存量及有无符号来区分。整型从最小到最大依次是:bool、char、signed char、unsigned char、short、unsigned short、int、unsigned int、long、unsigned long 以及C++11 新增的 long long和 unsigned long long。还有一种 wchar_t 类型,它在这个序列中的位置取决于实现。C++11 新增了类型char16_t和 char32_t,它们的宽度足以分别存储16和 32 位的字符编码。C++确保了 char 足够大,能够有储系统基本字符集中的任何成员,而wchart则可以存储系统扩展字符集中的任意成员,short 至少为16位,而 int 至少与 short 一样长,long 至少为 32 位,且至少和 int 一样长。确切的长度取决于实现。
字符通过其数值编码来表示。IO系统决定了编码是被解释为字符还是数字。浮点类型可以表示小数值以及比整型能够表示的值大得多的值。3种浮点类型分别是 foat、double 和long double。C++确保 foat 不比 double 长,而 double 不比 long double 长。通常,float 使用 32 位内存,double使用64位,long double 使用80到128位。
通过提供各种长度不同、有符号或无符号的类型,C++使程序员能够根据特定的数据要求选择合适的类型。
C++使用运算符来提供对数字类型的算术运算:加、减、乘、除和求模。当两个运算符对同一个操作数进行操作时,C++的优先级和结合性规则可以确定先执行哪种操作。对变量赋值、在运算中使用不同类型、使用强制类型转换时,C++将把值从一种类型转换为另一种类型。很多类型转换都是“安全的”,即可以在不损失和改变数据的情况下完成转换。例如,可以把int值转换为 long值,而不会出现任何问题。对于其他一些转换,如将浮点类型转换为整型,则需要更加小心。