1、变量的三种命名方式
a. C风格类型
_int_number_of_student
b. 驼峰表示法
numberOfStudent,sizeOfString
c.匈牙利标注法
iNumberOfStudent,charName
2、引子
C++中的输入输出操作由“流”来处理;流:指数据从一个位置流向另一个位置;提取操作:从流中获取数据的操作;插入操作:向流中添加数据的操作;
流对象(iostream.h)
cin:用来处理标准输入,即键盘输入;cout:用来处理标准输出,即屏幕输出;cerr:用来处理标准出错信息;
数据输出cout
(1)作用:将数据输出到外设(如屏幕);
(2)格式:cout<< 表达式1〔<< 表达式2 << 表达式3 … << 表达式n〕;
int a=2,b=3;
char c='x';
cout<<"a="<<a<<'\t'<<"b="<<b<<'\n';
cout<<"c="<<c<<'\n';
数据输入cin
(1)作用:从外设(键盘)输入数据到变量
(2)格式:cin>> 变量名1 〔>> 变量名2 >>变量名3 … >>变量名n〕;
其中,“>>”称为提取运算符,表示将暂停程序执行,等待用户从键盘上输入相应的数据。
int i,j;
cin>>i>>j;
(3)分隔符:空格或回车
(4)回车作用
①通知cin已输入一行数据,cin可从输入行提取输入数据,依次赋给变量;
②用作输入数据间的分隔符。
当cin遇到回车键时,若仍有变量没有得到数据,则继续等待用户输入新的一行数据。当cin遇到回车键时,输入行中的数据没有提取完,则可给其它变量赋值。
注意:
从键盘上输入数据的个数、类型、顺序,必须与cin列举的变量一一对应。
简单的输入/输出格式控制
C++中预定义了一些格式控制函数,可以直接嵌入到cin和cout中实现输入/输出数据格式的控制。使用这些格式控制函数时,必须在程序的开头包含iomanip.h文件,即增加一行:
#include <iomanip.h>
注意:
(1)当指明用一种进制输入/输出数据时,对其后的输入/输出均有效,直到指明又以另一种进制输入/输出为止;
(2)八进制或十六进制数的输入/输出,只能适用于整型数据,不适用于实型数据和字符型数据;
(3)域宽设置函数setw(int)仅对其后的一个输出项有效。
(4)实数的小数位数设置函数setprecision(int)对其后的所有输出项都有效,直到再一次设置为止。
即从键盘输入数据,输出到显示器屏幕。这种输入输出称为标准的输入输出,简称标准I/O。
C++的I/O操作是类型安全(type safe)的。C++的I/O操作是可扩展的,不仅可以用来输入输出标准类型的数据,也可以用于用户自定义类型的数据。
以外存文件为对象的输入输出称为文件的输入输出,简称文件I/O。
对内存中指定的空间进行输入和输出(通常指定一个字符数组作为存储空间,实际上可以利用该空间存储任何信息),这种输入和输出称为字符串输入输出,简称串I/O。
3、输入输出流
C++的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一对象。在输入操作时,字节流从输入设备(如键盘、磁盘)流向内存,在输出操作时,字节流从内存流向输出设备(如屏幕、打印机、磁盘等)。流中的内容可以是ASCII字符、二进制形式的数据、图形图像、数字音频视频或其他形式的信息。实际上,在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据。流是与内存缓冲区相对应的,或者说,缓冲区中的数据就是流。
在C++中,输入输出流被定义为类。C++的I/O库中的类称为流类(stream class)。用流类定义的对象称为流对象。cout(cout是console output的缩写)和cin并不是C++语言中提供的语句,它们是iostream类的对象。
头文件是程序与类库的接口,iostream类库的接口分别由不同的头文件来实现。与iostream类库有关的头文件,常用的有
iostream包含了对输入输出流进行操作所需的基本信息。
fstream用于用户管理的文件的I/O操作。
strstream用于字符串流I/O。
stdiostream用于混合使用C和C++的I/O机制时。
iomanip在使用格式化I/O时应包含此头文件。
在iostream头文件中定义的类有ios,istream,ostream,iostream,istream _withassign, ostream_withassign,iostream_withassign等。
iostream.h包含了对输入输出流进行操作所需的基本信息。在iostream.h头文件中不仅定义了有关的类,还定义了4种流对象。
1)四个流对象
cin是istream的派生类istream_withassign的对象,它是从标准输入设备(键盘)输入到内存的数据流,称为cin流或标准输入流。cout是ostream的派生类ostream_withassign的对象,它是从内存输入到标准输出设备(显示器) 的数据流,称为cout流或标准输出流。cerr和clog作用相似,均为向输出设备(显示器) 输出出错信息。因此用键盘输入时用cin流,向显示器输出时用cout流。向显示器输出出错信息时用cerr和clog流。
在iostream头文件中定义以上4个流对象用以下的形式(以cout为例):
ostream cout (stdout);
在定义cout为ostream流类对象时,把标准输出设备stdout作为参数,这样它就与标准输出设备(显示器)联系起来,如
cout<<3;//就会在显示器的屏幕上输出3。
cout流在内存中对应开辟了一个缓冲区,用来存放流中的数据,当向cout流插入一个endl时,不论缓冲区是否已满,都立即输出流中所有数据,然后插入一个换行符,并刷新流(清空缓冲区)。
cerr流对象是标准错误流,被指定为与显示器关联。cerr与标准输出流cout的作用和用法差不多。但有一点不同: cout流通常是传送到显示器输出,但也可以被重定向输出到磁盘文件,而cerr流中的信息只能在显示器输出。cerr流中的信息是用户根据需要指定的。
clog(console log)流对象也是标准错误流,作用和cerr相同。区别: cerr不经过缓冲区,直接向显示器上输出信息,而clog中的信息存放在缓冲区中,缓冲区满后或遇endl时向显示器输出。
#include <iostream>
#include <string>
using namespace std;
int main()
{
float a,b,c,disc;
cout<<"Please input a,b,c:";
cin>>a>>b>>c;
if(a==0) cerr<<"a is equal to zero,error!"<<endl;
else if((disc=b*b-4*a*c)<0)
cerr<<"disc=b*b-4*a*c<0"<<endl;
else {
cout<<"x1="<<(-b-sqrt(disc))/(2*a)<<endl;
cout<<"x2="<<(-b+sqrt(disc))/(2*a)<<endl;}
return 1;
}
2)格式输出
(1)使用控制符控制输出格式
C++的I/O 系统定义了一些用来管理I/O 格式的控制函数。它们不在类的封装之内,表面上也不一定以函数调用的形式出现,因此它们被称为格式控制符,格式控制符包括有参和无参的控制符,分别在两个头文件中说明。
定义在iostream.h 文件中的I/O 控制符有:
endl 输出时插入换行符并刷新流
ends 输出时在字符串后插入NULL 作为尾符
flush 刷新,把流从缓冲区输出到目标设备
ws 输入时略去空白字符
dec 令I/O 数据按十进制格式
hex 令I/O 数据按十六进制格式
oct 令I/O 数据按八进制格式
定义在iomanip.h 文件中的带参控制符有:
setbase(int a)
resetiosflags(long)
setiosflags(long)
setfill(char)
setprecision(int)
setw(int)
这些格式控制符大致可以代替ios 的格式函数成员的功能,且使用比较方便。例如,为了把整数457 按16 进制输入,可有两种方式:
int i=457;
cout.setf(ios:hex,ios::basefield);
cout<<i<<endl;或者:
int i=457;
cout<<hex<<i<<endl;
由例中可以看出采用格式控制符比较方便,二者的区别主要为:
(1) 用成员函数须增加限定前缀:“cout”,控制符是类外定义的无此要求。
(2) 用格式成员函数时要单独成一语句,不能用I/O运算符“<<”和“>>”与数据的I/O 写到一起。如cout<<hex<<i<<endl;那样。
从这个例中还发现,用标志状态字时,还要注意状态字的各个位对应的特征不是无关的。例如dec,hex,oct三者只能取其一,简单地用cin.setf(ios:dec)的形式可能出现问题:
cout.setf(ios::dec);
cout.setf(ios::oct);
这两个函数调用之后,在两个特征位置都为1,但输出不可能既是十进制又是十六进制。为了解决集中互斥属性不能同时设置的问题,ios 类中又定义了公有的静态常量:
static const long basefield //值为dec/oct/hex
static const long adjustfield //值为left/right/intenal
static const long floatfield //值为scientific/fixed
其使用方法为:
cout.setf(ios::scientific,ios::floatfield);
其第二个参数保证设置为科学表示法,同时不设置为定点表示法。
格式控制符的使用比较方便,但有些细节应在使用中注意。
fmtflags ios::flags(fmtflags newflags);
fmtflags ios::setf(fmtflags ored_flag);
fmtflags ios::unsetf(fmtflags clear_flag);
fmtflags ios::setf(fmtflags bits, fmtflags field);
fmtflags field用来保证同一种类型的值只设置一种,在设置新值时,先清除先前设置过的值。常用后三种
(1)有些控制符与对应的格式成员函数功能一致,例如:
setiosflags(long)与函数long setf(long)的功能一致;
resetiosflags(long)则与函数long unsetf(long)的功能一致。
(2) setfill(char),setw(int)和setprecision(int)是三个常用的有参控制符,
其中:
setw(n)为数据域宽。如果数据实际宽度小于n 则以填充字符填完;如果数据实际宽度大于n,则原数照常输出,并不删除任何一位,参数n 的缺省值为0。setw(n)的使用与函数width(n)除了上面讲的之外,还有一点不同即setw(n)的有效范围只涉及后面的一个I/O 数据,这与width(n)的情况不同,后者的设置一直保持到有新的设置为止。setprecision(n)与函数precision(n)的功能一致,缺省的精度值为n=6。setfill(c)与函数fill(c)的功能一致,缺省的填充字符为空格。
(2)用流对象的成员函数控制输出格式
除了可以用控制符来控制输出格式外,还可以通过调用流对象cout中用于控制输出格式的成员函数来控制输出格式。流成员函数setf和控制符setiosflags括号中的参数表示格式状态,它是通过格式标志来指定的。格式标志在类ios中被定义为枚举值。因此在引用这些格式标志时要在前面加上类名ios和域运算符“::”。
在类ios 的说明中,列出下面一些用于格式控制的公有成员函数:
long flags(); //返回当前标志字
long flags(long); //设置标志字并返回
long setf(long); //设置指定的标志位
long unsetf(long); //清除指定的标志位
long setf(long,long); //设置指定的标志位的值
int width(); //返回当前显示数据的域宽
int width(int); //设置当前显示数据域宽并返回原域宽
char fill(); //返回当前填充字符
char fill(char); //设置填充字符并返回原填充字符
int precision(); //返回当前浮点数精度
int precision(int); //设置浮点数精度并返回原精度(指小数点后的位数)
所涉及的标志字又称标志状态字,它是一个long 类型(长整型)的变量。状态字的各位都控制一定的I/O 特征,例如标识状态字的右第一位为1,则表示在输入时跳过空白符号。状态字的各位以枚举类型形式定义于ios 说明中:
enum{
skipws=0x0001 //输入时跳过空白
left=0x0002 //左对齐输出
right=0x0004 //右对齐输出
internal=0x0008 //在符号位和基指示符后填充
dec=0x0010 //十进制格式
oct=0x0020 //八进制格式
hex=0x0040 //十六进制格式
showbase=0x0080 //输出标明基数说明
showpoint=0x0100 //输出浮点数带小数点
uppercase=0x0200 //十六进制大写输出
showpos=0x0400 //输出正整数带+号
scientific=0x0800 //输出浮点数用科学表示法
fixed=0x1000 //输出浮点数以定点形式
unitbuf=0x2000 //插入后刷新流缓冲区
stdio=0x4000 //插入后刷新stdout 和stderr
};
cin.flags()返回当前的(键盘)输入流中的标志状态字,但它一般不单独使
用。
cin.flags(cin.flags()|ios::skipws);
这个函数的调用,其实参为两个状态字的“或”运算的结果。其功能是在原有的状态不变条件下,输入时跳过空白。
cout.flags(cout.flags()|ios::showbase);
此函数调用结果为要求输出时标明数制基数符,其它设置不变。如果要求不标明基数符,则需执行:
cout.flags(cout.flags()&~ios::showbase);
用setf 函数有时可能比较方便:
cin.setf(ios::skipws);
同样是要求输入时跳过空白。为了改变这一设置,令其输入时不跳过空白
可用下面的两种方式之一:
cin.unsetf(ios::skipws);或cin.setf(0,ios::skipws);
再如:cout.unsetf(ios::uppercase);可令十六进制数以小写字符输出,而
cout.setf(1,ios::uppercase);则可令其大写输出。
其余函数更为常用,同时也比较简单:
cout.width(12);设置数据宽度位12,
cout.precision(4);输出浮点数时小数点后取4 位,
cout.fill('#');要求输出中用‘#’填充空白。
例如:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout.setf(ios::scientific);
cout.setf(ios::showpos);
cout<<2345<<23.4567<<endl;
cout.precision(2);
cout.width(10);
cout<<2345<<23.4567<<endl;
cout.unsetf(ios::scientific);
cout.fill('#');
cout.width(8);
cout<<2345<<23.4567<<endl;
return 1;
}
当然了,还有用户自定义的格式控制符。
再举两个例子:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
int a;
cout<<"input a:";
cin>>a;
cout<<"dec:"<<dec<<a<<endl;
cout<<"hex:"<<hex<<a<<endl;
cout<<"oct:"<<setbase(8)<<a<<endl;
char* pt="China";
cout<<setw(10)<<pt<<endl;
cout<<setfill('*')<<setw(10)<<pt<<endl;
double pi=22.0/7.0;
cout<<setiosflags(ios::scientific)<<setprecision(8);
cout<<"pi="<<pi<<endl;
cout<<"pi="<<setiosflags(ios::fixed)<<pi<<endl;
return 1;
}
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
int a=21;
cout.setf(ios::showbase);
cout.unsetf(ios::dec);
cout.setf(ios::hex);
cout<<"hex:"<<a<<endl;
char* pt="China";
cout.width(10);
cout<<pt<<endl;
cout.width(10);
cout.fill('*');
cout<<pt<<endl;
double pi=22.0/7.0;
cout.setf(ios::scientific);
cout<<"pi=";
cout.width(14);
cout<<pi<<endl;
return 1;
}