第三章 处理数据
简单变量
- 命名规则
1.在名称中只能使用字母、数字、下划线
2.名称的第一个字符不能使数字
3.区分字符大小写
4.不能将C++关键字用作名称
5.以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符。
6.不限长度,名称中的所有字符都有意义
如果想要两个或多个单词,用下划线将单词分开。或者从第二个单词开始讲每个单词的第一个字母大写,如myEyeTooth。
整型
- 整型short、int、long、long long
4种都是符号类型。
1.short至少16位;
2.int至少和short一样长;
3.long至少32位,且至少与int一样长;
4.long long 至少64位,且至少与long一样长。
计算机内存的基本单元是位(bit)。
字节(byte)通常指的是8位的内存单元。
1kB=1024字节
1MB=1024kB
c++字节由至少能够容纳实现的基本字符集的相邻位组成。可能取值的数目必须等于或超过字符数目。
类型的长度:sizeof返回类型或变量的长度,单位为字节
//limits.cpp--some integer limits
#include <iostream>
#include <climits>
int main(){
using namespace std;
int n_int=INT_MAX;
short n_short=SHRT_MAX;
long n_long=LONG_MAX;
//long long n_llong=LLONG_MAX;
cout<<"int is"<<sizeof(int)<<"bytes."<<endl;
cout<<"short is"<<sizeof n_short<<"bytes."<<endl;
cout<<"long is"<<sizeof n_long<<"bytes."<<endl;
//cout<<"long long is"<<sizeof n_llong<<"bytes."<<endl;
cout<<endl;
cout<<"Maxuimum values:"<<endl;
cout<<"int:"<<n_int<<endl;
cout<<"short:"<<n_short<<endl;
cout<<"long:"<<n_long<<endl;
//cout<<"long long:"<<n_llong<<endl<<endl;
cout<<"Minimum int value="<<INT_MIN<<endl;
cout<<"BIts per byte="<<CHAR_BIT<<endl;
return 0;
}
对类型名(如int)使用sizeof,应把名称放在括号中;但对变量名(如n_short)括号是可选的。
-
初始化
int owls=101; //传统C语言初始化语法
int wrens(432); //c++的另一种初始化语法
用于数组和结构的初始化方式,等号可用可不用
int hamburgers={24};
int emus{7};
int rocs={}; //大括号不含任何东西,变量初始化为零。
通过使用大括号新增的大括号初始化器,初始化常规变量与初始化类变量的方式更像。c++11使得可将大括号初始化器用于任何类型。
4种整型都有一种不能储存数值的无符号变体,其优点是可以增大变量能够存储的最大值。如short表示的范围是-32768到+32767,则无符号版本的范围为0-65535.
创建无符号版本的基本整型,用unsigned修改声明即可:
unsigned short change;
注意 unsigned 本身是unsigned int的缩写。将一个short变量(sam)和一个unsigned short变量(sue)分别设置为最大的short值,即32767→变量+1→sam=-32768,sue=32768
将两个变量设置为0:→变量-1→sam=-1.sue=65535
可见,如果超越了限制,值将从变为范围的另一端的值
c++不保证符号整型超越限制(上溢和下溢)时不出错。 -
选择整型类型
通常选int
如果变量表示的值不可能为负,如文档中的字数,则可用无符号类型,这样变量可以表示更大的值。
如果知道变量可能表示的整数值大于16位整数的最大可能值,则使用long。
如果要存储的值超过20亿,使用long long。
如果short比int小,使用short可以节省内存。如果节省内存很重要,使用short而不是int。 -
整型字面值:
c++能以三种不同的计数方式来书写整数:基数为10、8、16.。
如果第一位为1-9,基数为10;
第一位为0,第二位1-7,基数8;
前两位为0x或0X,基数16。
#include <iostream>
int main()
{
using namespace std;
int chest=42;
int waist=0x42;
int inseam=042;
cout<<"chest="<<chest<<"(42 in decimal)\n";
cout<<"waist="<<waist<<"(0x42 in hex)\n";
cout<<"inseam="<<inseam<<"(042 in octal)\n";
return 0;
}
在默认情况下,cout以十进制格式显示整数,而不管这些整数在程序中怎么写的。
这些都是为了表达上的方便,在计算机中都被存储为二进制数。
如果要以十六进制或八进制方式显示值,头文件iostream 提供了控制符dec、hex、oct分别用于以十进制、十六进制、八进制显示整数。
#include <iostream>
int main()
{
using namespace std;
int chest=42;
int waist=42;
int inseam=42;
cout<<"chest="<<chest<<"(42 in decimal)\n";
cout<<hex;
cout<<"waist="<<waist<<"(42 in hex)\n";
cout<<oct;
cout<<"inseam="<<inseam<<"(42 in octal)\n";
return 0;
}
诸如cout<<hex;代码不会再屏幕上显示任何内容,而只是修改cout显示整数的方式。
- c++如何确定常量的类型:
一般将整型常量存储为int类型,除非用了特殊后缀,值太大,不能存储为int。
后缀:l或L表示long,u或U表示unsigned int,ul(无关顺序,大小写)表示unsigned long。 - char类型:字符和小整数
为存储字符(如字母和数字)而设计的,通过使用字母的数值编码解决存储字母的问题,因此,char类型是另一种整型。能够表示计算机系统的所有基本符号——所有的字母、数字、标点符号等。
上述代码,cin和cout完成了字符的转换工作:
cin将键盘输入的M转换为77,cout将77转换为M
c++中对字符用单引号,对字符串用双引号。
cout.put()函数,该函数显示一个字符。
#include <iostream>
int main(){
using namespace std;
char ch='M';
int i =ch;
cout<<"The ASCII code for "<<ch<<" is "<<i<<endl;
cout<<"Add one to the character code:"<<endl;
ch=ch+1;
i=ch;
cout<<"The ASCII code for "<<ch<<" is "<<i<<endl;
//cout.put(ch);
//cout.put('!');
return 0;
}
值的类型将引导cout如何显示值
ASCII系统中的对应情况:
‘A’→65;‘a’→97;‘5’→53;‘ ’→32;‘!’→33
转义序列:
换行符:\n;水平制表符:\t;(Tab)垂直制表符:\v;退格:\b;回车:\r;
八进制编码032:\032;十六进制编码0x1a:\x1a
-
signed char and unsigned char
如果将char用作数值类型,signed char表示-127-128,unsigned char表示0-256,假设要用char 表示一个200大的值,则使用unsigned char 可以在任何系统达到这种目的。 -
wcha_t
可以扩展字符集,是一种整数类型,有足够的空间,对底层类型的选择取决于实现。
wcin wcout可用于处理wchar_t流,可通过加上前缀L来表示宽字符常量和宽字符串 -
char16_t 和char32_t
c++11新增的类型,两者都是无符号的,前者16位,后者32
使用前缀u表示前者常量,使用U表示后者常量。 -
bool类型
值为true或false -
const限定符
如果程序在多个地方使用同一个常量,则需要修改该常量时,只需修改一个符号即可:
const int Mouths=12;
常量被初始化后,其值就被固定了,编译器不允许在修改该常量的值。
一种常见的做法是 名称首字母大写,或整个字母大写,以k字母打头,如kmouths。
应在声明中对const初始化,下面的代码不好:
const int toes;
toes=10;
如果在声明常量时没有提供值,则该常量的值将是不确定的,且无法修改。
浮点数
- 书写
1.标准小数点:12.34
2.E表示法:3.45E6,3.45与10的6次方相乘
E非常适合非常大和非常小的数。
既可以使用E 或e ,指数可以是负数或正数。
但数字中不能有空格。 - 浮点类型
float、double、long double这些类型按他们可以表示的有效数位和允许的指数最小范围来描述的。有效位是数字中有意义的位:
14000,两个有效位;14.162,5个有效位
对于有效位数的要求是:float至少32位,double至少48位,且不少于float,long double至少和double一样多。这三种类型的有效位数可以一样多,通常float为32位,double为64位,long double为80、96、128位,三种类型的指数范围至少是-37到37
#include <iostream>
int main(){
using namespace std;
cout.setf(ios_base::fixed,ios_base::floatfield);
float tub=10.0/3.0;
double mint=10.0/3.0;
const float million=1.0e6;
cout<<"tub="<<tub;
cout<<",a million tubs= "<<million*tub;
cout<<",\nand ten million tubs= ";
cout<<10*million*tub<<endl;
cout<<"mint="<<mint<<"and a million mints=";
cout<<million*mint<<endl;
return 0;
}
setf()迫使调用输出使用定点表示法,以便更好地了解精度,防止程序把较大的值切换为E表示法,并使程序显示到小数点后6位。
通常cout会删除结尾的零,调用cout.setf()将覆盖这种行为
从上面程序的输出可以看出,tub在7位有效位上是精确的(float至少有6为有效位),然而double类型的变量显示了13个3,至少有13位是准确的。
- 浮点常量
默认情况下,像8.24和2.4E8这样的浮点常量都属于double类型。如果希望常量为float类型,使用f或F后缀,对于long double 使用l或L后缀
浮点数可以表示整数之间的值,其次因其有缩放因子,可以表示的范围大得多。另一方面,浮点运算的速度通常比整数运算慢,且精度将降低。
int main(){
using namespace std;
float a=2.34e+22f;
float b=a+1.0f;
cout<<"a= "<<a<<endl;
cout<<"b-a="<<b-a<<endl;
return 0;
}
该程序将数字加1,再减去原来的数字。结果应为1,但显示结果为0。
问题在于,2.34e+22是一个小数点左边有23位的数字。加1是在第23位上加,但float类型只能表示数字中的前6位或前7位,因此修改23位对这个值不会有任何影响。
算术运算符
±*/%
%的两个操作数都必须为整型,如果其中一个是负数,则结果的符号满足如下规则:(a/b)*b+a%b=a
(/) 除法运算:如果两个操作数都是整数,则结果的小数部分将被丢弃。
-
类型转换
由于有11种整型和3种浮点型,c++自动执行类型转换:
1.将一种算术类型的值赋给;另一种算术类型的变量时,c++将对值进行转换;
2.表达式中包含不同的类型时,c++将对值进行转换;
3.将参数传递给函数时,c++将对值进行转换。 -
初始化和赋值进行的转换
例:so_long的类型为long,thirty的类型为short
so_long=thirty;
进行赋值时,程序将thirty的值(通常是16位)扩展为long值(通常是32位)。扩展后将得到一个新值,这个值被存储在so_long中,而thirty的值不变。
将一个值赋给值取值范围更大的类型通常不会导致什么问题,但将一个很大的long值赋给float变量将降低精度。
将0赋给bool变量时,将被转换为false;非零被转换为True。 -
以{}方式初始化时进行的转换:
c++将使用大括号的初始化称为列表初始化,列表初始化不允许缩窄,即变量的类型可能无法表示赋给他的值。例如,可将long变量初始化为int值,因为long总是至少与int一样长,相反方向的转换可能也被允许,只有int变量能够存储赋给它的long常量。 -
表达式中的转换
在计算表达式时,c++将bool、char、unsigned char、signed char和short值转换为int。true被转换为1,false被转换为0。这些转换被称为整型提升。