C++教程1Word下载.docx
《C++教程1Word下载.docx》由会员分享,可在线阅读,更多相关《C++教程1Word下载.docx(91页珍藏版)》请在冰点文库上搜索。
类指针…………………………………………………………57
基类、派生类指针……………………………………………58
虚函数…………………………………………………………59
函数模板………………………………………………………62
类模板…………………………………………………………64
后记…………………………………………………………………66
参考文献……………………………………………………………67
第一篇C++基础
内容提要
这一篇讲的是C++的非面向对象方面的内容,是进行程序设计的基本知识。
它讲述了C++中C语言的成分,以及C++对C语言的扩展,当然这些内容也就是程序设计的基本概念了。
//ex010001.cpp
//C++语言的最小框架。
00main()
01{
02}
这是最简单的C++程序,它什么也不做,只是一个基本的框架。
main是程序的入口点。
它和C语言没什么不同。
因为C++是C语言的一个扩展,有一种说法就是C++是“带类的C语言”。
但是一定不要简单地认为C++就是C的超集,当我们使用C++的时候,我们的思想和用C语言编程的时候是有很大的不同的。
因为C++是真正的面向对象的语言:
Object-OrientedLanguage,我们要慢慢地习惯于用面向对象的思考方法去解决问题。
下面举的一些例子,许多完全可以用C语言来实现它,但是如果这样做的话,是一种倒退。
如果你对C语言不是很熟悉,不要紧。
学习C++的过程也就是巩固和掌握C语言的过程。
C与C++都是语言,况且后者是在前者的基础上发展起来的,因此,我认为,两者有相通之处。
尤其是这一篇,涉及了许多C语言方面的内容。
但是更主要的是:
你将对C++语言有一个初步的了解。
C++沿用了C语言的习惯,程序的基本结构有很大的相似。
它一般包含以下两个主要成分:
[包含文件]
[主控文件]
前者中有用#include包含的库文件、用户文件(就是你自己编写的)、定义文件等内容。
这样,C++就继续保持着C语言简练的优秀特性,使我们能层次分明地了解程序的结构、组成。
后者就是main()函数的内容了。
它是程序的入口点。
如C语言一样,C++实际源代码包含在一个或多个源文件中,然后,被编译、连接起来。
在VC++集成环境中,鼓励你把定义文件、实现文件分开,这是有好处的。
但是当我们进行Windows下编程的时候,有时候我们在编译环境中看不到main这个头。
看到的是WinMain(主要是以前用C来进行Windows3.x下编程的时候),这其实就是Windows下的程序入口了。
现在我们很可能连这个也找不到,当我们用MFC进行VC++程序设计的时候,就是这种情况。
其实MFC类库已经把主函数包含进去了。
关于这些内容,暂且不做讨论。
值得一提的是:
如果在一个程序中多次包含了同一个文件,则会引起重复定义的错误。
如包含了两次mycpp.h这个定义文件。
可以这样解决:
在书写mycpp.h的时候,写成如下的形式:
#ifndefMYCPP_H
#defineMYCPP_H
……//mycpp.h里的定义内容
#endif
//ex010002.cpp
//有关C++中的标准输出流的。
01#include<
iostream.h>
02#include<
iomanip.h>
03
04voidmain(void)
05{
06cout<
<
10101<
endl;
07cout<
0.123<
08cout<
1<
0<
09cout<
”MyNumberis:
”<
10cout<
”MyNameisTom!
\n”;
11
12cout<
”Oct:
oct<
21<
13cout<
”Hex:
hex<
14cout<
”Dec:
dec<
15
16cerr<
”Thismessageisdisplayedonscreen.\n”;
17
18cout<
setw(3)<
19cout<
setw(6)<
20}
上面这个程序的输出是:
10101
0.123
MyNumberis:
MyNameisTom!
Oct:
25
Hex:
15
Dec:
21
Thismessageisdisplayedonscreen.
10101
这个程序关于C++中的输出流cout的。
iostream.h是一个很重要的头文件,它提供了有关输入输出操作的基本函数和宏定义。
当我们用#include把它包含进来后,我们在程序中可以使用在iostream.h文件中的定义的类、函数等;
C++编译你的程序时,将把你所用到的过程联编到你的.obj和.exe等文件中,没有用到的不会编译到你的程序中去的。
00行说明的就是这些内容。
在01行包含iomanip.h后,17、18行中的setw()就可以使用了,它用来设置输出数据的宽度。
cout是一种类对象,后面的cin也一样。
它们有自己的实现函数。
以后我们再来研究。
现在要知道的就是cout实现的功能相当于C语言中的printf函数,它是向屏幕输出内容的。
从05-09行我们可以看出,用cout输出时,我们不必指定输出内容的类型,我们只须把内容给出就行了,由cout自动识别。
‘<
’是一个‘重定向’符。
这里我借用Dos的一个命名。
在Dos命令窗中,比如有一个可执行文件abc.exe,它向屏幕输出一百个整数;
如果我们输入abc>
>
a.txt,那么一百个整数将输入到文件a.txt中。
上面说,cout是一个输出流,姑且可以认为它是代表显示器,那么用cout<
10101就表示把10101输出到显示器上(以后可以看到它不同的功能)。
我们看一下15行,cerr的作用也是输出内容,但是它叫做‘出错输出流’。
意思是它输出的内容表明一个错误信息,或是输出一个强制可见的信息。
其实它在输出信息的作用上和cout是一致的。
只是当我们在Dos命令窗口中进行重定向时,它输出的信息不会被重定向到指定的文件中;
当我们在文件abc.exe中有cerr输出语句,那么它的内容将始终输出到屏幕上,执行abc>
a.txt,文件a.txt中不会有cerr的输出内容。
你在上面的程序中看到的endl,它表示回车换行,如5-8行中所示。
而在字符串中‘\n’也代表这个意思,如9、15行所示。
11-13行指定输出数据的形式。
这是一种格式化输出。
如果觉得有问题的话,想一想printf函数(printf(“%o%x%d”,21,21,21);
效果是一样的)。
C++在输出整数时缺省是一十进制(Dec)的形式;
如果在某处说明了输出形式,那么后续的输出豆浆使用这种形式。
如果把12行改为cout<
那么它将按11行所定义的8进制形式输出25。
C++用//来表示注释,这一行其后的内容就全部是注释部分;
如第2行。
当然也可使用/*与*/来把整段内容作为注释,这是沿用C语言的习惯。
注意,用/*与*/注释是不能嵌套的,也就是不能有这样的形式:
/*
/*
……
*/
*/
//ex010003.cpp
//C++中变量、标准输入流的。
01#include<
02voidmain(void)
03{
04charcTemp;
//-128To127
05intnTemp;
//-32768To32767或–65536To65535
06unsigneduTemp;
//0To65535
07longlTemp;
//-2147483648To2147483647
08floatfTemp;
//-3.4*10exp(-38)To3.4*10exp(38)
09doubledTemp;
//-1.7*10exp(-308)Tom1.7*10exp(308)
10
11cTemp=’a’;
12nTemp=123;
13uTemp=12345;
14lTemp=1234567;
15fTemp=1.23;
16dTemp=1.233
17cout<
”input:
char,int,uint,long,float,double:
18cin>
cTemp;
19cin>
nTemp>
uTemp>
lTemp;
20cin>
fTemp>
dTemp;
21
22cout<
”char:
”<
cTemp<
23cout<
”int:
nTemp<
endl
24cout<
”unsigned:
uTemp<
25cout<
”long:
lTemp<
26cout<
”float:
fTemp<
27cout<
”double:
dTemp<
28}
C++中的变量说明的规则与C是相同的。
各个基本变量的值域如3-8行注释所示。
不同的编译器在规定上有一些差别,如Vc++定义int型为4Byte,而BorlandC++定义其为2Byte。
10-15行是对已经说明的变量进行赋值。
在对变量进行赋值的时候,一定要注意它的取值范围,若超出它的范围,会发生溢出错误。
对于溢出,如果把结果化成二进制的形式去理解,是比较直观的。
17-18行是C++中的输入操作,类似于C中的scanf。
它是一个输入流,与cout的作用正好相反。
‘>
’是另一中‘重定向’符,也称为抽取符。
你可以把它看作是从键盘上输入的流(与cout类似,你可以认为cerr代表显示器)。
然后赋给后面跟着的变量,如17行。
18、19行则是一次输入几个变量值得语句,这里‘>
’似乎又取到了分隔符的作用,当你从键盘上输入各个值后,会一一对应到相应的变量。
若输入的内容与变量的类型不一致,则会发生错误。
你可以试一试这个程序,观察一下运行情况。
在我们说明一个变量的时候,应尽量使用比较直观的名称,而且最好使用所谓的‘西班牙’命名法。
如程序中所示:
指在一个变量名前直观地指出它的类型。
如字符型就在它前面冠以‘c’,短整型就在它前面冠以‘n’等等。
下面列出了这些前缀及其含义:
前缀
含义
b
布尔型
c
字符型
dw
(32位)无符号长整数
F
位标志,组装成一个16位整数
H
16位句柄
L
(32位)长整数
Lp
(32位)长指针
N
(16位)短整数
P
(16位)短指针
Pt
X和y坐标,组装成一个无符号32位整数
Rgb
RGB颜色值,组装成一个32位整数
w
(16位)无符号短整数
在Windows下,系统用typedef为我们定义了许多新的数据类型的名字及结构类型的名字,便于记忆。
常用的有:
类型
BOOL
16位布尔值
LONG
32位有符号整数
HANDLE
用做句柄的16位无符号整数
HWND
在窗口中用做句柄的16位无符号整数
LPSTR
32位指向char类型的指针
FARPROC
32位函数指针
另外,当我们使用浮点型数据的时候,一定要注意它的精度。
通常,你如果要打印一个float型变量a,它的值为0.3999999。
你使用cout<
a;
那么将打印出0.4。
所以我们应尽量避免两个浮点数之间的比较:
floata,b;
a=0.123456780;
b=0.123456784;
if(a==b)
{
//result_1
}
else
//result_2
上面的程序段,if语句中result_1的内容将被执行。
//ex010004.cpp
//关于简单运算。
04inta;
05a=3;
06
a++<
’‘;
a<
++a<
11}
我在这里只强调一下自加运算(自减运算同理),其它的凡是C语言支持的运算,C++是全部适用的。
而扩展部分我将在后续的章节中一一指出。
自加运算分为后缀与前缀,记住:
a++指使用了a的值以后再使a加1;
++a指使用a的值以前先使a的值加1;
上面程序的结果是:
3455
至于运算的优先级,是一个细节问题,我们经常会忽略它的。
在实际运算中,还涉及到从左到右和从右到左计算的问题。
计算下面程序片断中变量a的值(初始值:
a=1,b=2):
a=b+a+++a,++b+a;
结果:
a=5。
不能硬性的记背优先级,而是应当在具体的应用中不断地了解、掌握它。
下表列出的内容有许多是全新的,在以后才涉及。
你可以把它作为一个参考表,有问题的时候查看一下。
运算符
名称
实例
:
作用域分辨符
class_name:
class_member_name
全局作用域分辨符
variable_name
.
成员选择符
object.member_name
->
pointer->
member_name
[]
下标
pointer[element]
()
函数调用
expression(parameters)
构造值
type(parameters)
Sizeof
对象大小
sizeofexpression
类型大小
sizeof(type)
++
后缀递增
Variable++
前缀递增
++variable
--
后缀递减
Variable--
前缀递减
--variable
&
引用运算符
variable
*
地址运算符
*pointer
New
分配内存运算符
newtype
Delete
释放内存运算符
deletepointer
delete[]
释放数组运算符
delete[]pointer
~
求反运算符
~expression
!
NOT运算符
expression
+
一元加法
+1
-
一元减法
-1
类型转换符
(type)expression
.*
object.*pointer
object->
乘法运算符
expression*expression
/
除法运算符
expression/expression
%
取模运算符
expression%expression
加法运算符
expression+expression
减法运算符
expression-expression
//ex010005.cpp
//这里是关于基本语句:
判断、循环等。
02
03voidmain(void)
04{
05for(intnum=’0’;
num<
=9;
num++)
06if(num%2==0)cout<
num;
endl<
08
09inta;
10cin>
11switch(a)
12{
13case0:
14case2:
15case4:
16case6:
17case8:
cout<
”Itisanevennumber.”<
18break;
19case1:
20case3:
21case5:
22case7:
23case9:
”Itisanoddnumber.”<
24}
25
26a=1;
27while(a<
1)
28{
29cout<
30a++;
31}
32cout<
33
34a=1;
35do
36{
37cout<
38a++;
39}while(a<
1)
40}
C++中的if-else、switch、for、while、do-while等语句是组成该语言的基本成分。
值得一提的是,在
上面是一个简单的程序。
要注意的是,while语句与do-while语句的区别。
上面24-30行是没有输出结果的。
而32-37行执行后将输出1。
象这些语言上的细节,希望应用的时候仔细一点。
也许你以为这没什么大不了的,但是我曾经在这方面有过错误的。
看一下第3行,num变量在for语句中说明;
第7行说明了一个新的变量a。
它们的有效范围是从说明开始到程序段结束。
//ex010006.cpp
//我们来讨论数组与字符串。
string.h>
05intAn_Array[20];
06charA_String[20];
07
08for(inti=0;
i<
20;
i++)
09{
10An_Array[i]=i;
11A_String[i]=’a’+i;
12}
13A_String[i]=’\0’;
14
15for(i=0;
16cout<
An_Array[i];
A_String<
18
19charTemp_String[10];
20strcpy(Temp_String,A_String+10);
21cout<
Temp_String<
22
”Inputastring:
”;
24cin>
A_String;
”Thestringinputtedis:
”Uppercase:
strupr(A_String)<
”Lowercase:
strlwr(A_String)<
说到数组、字符串,我们很自然地要谈起指针。
你知道,被执行的程序,或者确切点说,进程,它的代码,数据最终都要放到内存中才能使用的。
这里我们讨论它的数据。
内存是一个一维的线性空间,每一个单元都有唯一的编号(当然这些编号是人为的),为了取得内存中的数据,我们首先要知道这个编号,也就是所谓的地址,而指针呢?
是一个专业化的名词罢了,它实际上指的就是那个编号(地址)。
数组和字符串提供了用一个名称来代表一堆相同类型数据(后者只是字符)的方法。
在C++语言中,数组中数据的类型始终是一致的。
其实,数组(字符串说到底是一种特殊的数组)这种表示方法是基于‘偏移量’的思想的,也就是