}
(3)带参数的宏和内联函数和红相似
#defineabs(n)((n)<0?
-(n):
n)
Inlineintabs(intn){returnn<0?
-n:
n}//ternaryoperator
但二者有区别:
调用内联函数由编译器处理(compile);
调用宏由预处理器(preprocessor)做扩展。
1.3.6ParameterDefault
C++中可为函数参数设初值。
若有语句:
Floatpow(intn,floatm,doublex=-1,inty=0);
则以下调用语句等价
Pow(3,2,3,-1,0)
Pow(3,2,3,-1)
Pow(3,2,3)
注:
(1)编译器按从左到右的顺序将实参与形参结合。
(2)参数缺省按从左向右顺序进行。
Voidfonc(intx,charc=’a’,floatm)//错误
#include
Voidmain()
{
doublex=2.4;
doubleabc(doublef,intn=2);//隐含计算fn=f2;
cout<Cout<}
Doubleabc(doublef,intn)
{
Doubletemp=t;
For(inti=2;i<=n;i++)
Temp*=f;
Returntemp;
Passbyaddress传址(按地址传送)
Passbyvalue传值(按值传递)
注:
C++中参数传递方式
Passbyname传名(按名传递)
Passbyreference引用传递
1.3.7ReferenceType
引用类型的声明:
类型&引用名=变量名;//&引用运算符
如:
intx=b;
Int&px1=x;//px1本是不是一个变量,只是变量X的一个别名
//px1和x代表同一个内存单元
Int&px2=px1//变量X的另一个别名,而不是px1的别名
对上述说明,若有:
Px1=5则x=5,px1=5,px2=5
Px2=7则x=7,px1=7,px2=7
X=6则x=6,px1=6,px2=6
注:
(1)引用类型的实质
Intnum=0;
Int&fnum=num;//&引用运算符
Int*pnum=#//&取地址运算符
//&逻辑位与,|逻辑位或,^逻辑异或
0xff4
(num的地址)
0xff4
Int*pnum=#
pnum
Int&fnum=num;
fnum
0
Intnum=0;
num
名内存单元
(2)引入引用的主要目的是建立各种不占有实际空间的虚实体,它作为函数参数时,
保证把实体的地址而不是实体本身传给函数,使人觉得直接而实在(和指针—地址相比)。
#include
Voidmain()
{
Intx=0;
Intf1(int*);//指针作为参数
Intf2(int&);//引用作为参数
Cout<<”x=”<f1(&x);//passbyaddress
Cout<<”x=”<f2(x)//passbyreference
cout<<”x=”<}
Intf1(int*px)
{
*px+=10;
}
Intf2(int&xx)
{
xx+=10;
}
输出结果:
x=0
x=10
x=20
1.3.8PointersandconstMondifer
1.Nowritingpointers
禁写指针/指针常量/长指针=恒指向某一地址时指针
格式如下:
数据类型*const指针变量名;
若有:
intr=6,b=2;
int*constpr=&r;
则:
*pr=10;√//r的值为10,指针被禁写,但其间接引用未被禁写
pr=&b;╳
2.Nowritingindirectreference//禁写实体
const数据类型*指针变量名;//指向常数的指针
若有:
intx=5,y=9;
constint*px;
px=&x;//合法,此时*px==5
px=&y;//合法,此时*px==9
*px==10;//非法
3.Nowritingbothofpointersandindirectreferences
const数据类型*const指针变量名;
constint*constpx=&x;
//px是一常指针,它指向—禁写实体,并且指针本身也被禁写
px=&变量名;//非法
*px=……//也非法
…
x
…
Px
x
x
1.3.9FunctionOverloading
函数重载是C++实现多态性的一种机制(还有函数模板,类模板两种)。
C++中可有如下函数定义:
//求两个数的最大值
intmain(intx,inty)//version1
{
returnxy:
x;
}
floatmax(floatx,floaty)//version2
{
returnxy:
x;
}
doublemax(doublex,doubley)//version3
{
returnxy:
x;
}
以上三个函数在同一作用域时,就是函数重载(C中肯定会错)。
若有:
floatm1=4.3,m2=2.6;
则max(m1,m2)指调用version2
注:
使用重载函数必须要求:
(1)函数名相同;
(2)参数个数不同或至少一个参数类型不同。
doublecount(intn);
doublecount(intn,charc);
1.3.10TypeParameterizing
实现多态性的另一种方法是使用genericity(类属—类型参数化)。
C++将类属实现为模板。
template//函数模板,写代码比函数重载简单
typemax(typex,typey)
{
return(xy:
x);
}
为使用函数,须将模板参数实例化。
将模板参数实例化的函数称为模板函数(templatefunctiong)
显示模板函数隐式模板函数
template
typemax(typex,typey)
{
return(xy:
x);
}
floatmax(float,float);
voidmain()
{
max(2.6,3.0);//解释为double
max(1.5,2);//错误实例化具有三义性
max(4,3);//解释为int
}
template
typemax(typex,typey)
{
return(xy:
x);
}
floatmax(float,float);
voidmain()
{
max(2.6,3.0);
max(1.5,2);
max(3,4);
……
}
隐式模板函数的类型参数只有在调用时才能确定,且按最先遇到的实参类型隐含地生成以一个模板函数。
例:
求若干个数的和
#include
#include
template
Tsum(T*array,intsize=0)
{
Ttotal=0;
for(inti=0;itotal+=array[i];
returntotal;
}
intintarr[]={1,2,3,4,5};
doubledouarr[]={1.1,2.2,3.3,4.4,5.5};
voidmain()
{
inttotal=sum(intarr,5);
doubledtotal=sum(douarr,5);
cout<cout<}
注:
对inttotal=sum(intarr,5)首先用intarr去初始化T类型。
intarr为整形数组,是一个指向int类型的指针,因而将原型解释为:
intsum(int*array,intsize=0);
即将T解释为int,而不是int*。
△函数模板适用于:
函数名相同,算法相同,参数个数也相同的问题
函数重载适用于:
函数名相同,算法相同,但参数个数或类型不相同的问题。
1.3.11DynamicMemoryAllocation
calloc()//calloc(n个,字节数)
C语言进行动态分配的三个函数malloc()//malloc(字节数)
free()//free(指针名)
C++提供new和delete运算符动态创建和撤消存储对象。
C++提供new和delete运算符动态创建和撤消存储对象
1.newOperator
new有三种用法:
(1)new类型//分配系统定义的基本类型实体
(2)new类型(表达式)//动态分配的同时进行初始化
(3)new类型【表达式】//动态分配数组(连续的若干个单元空问)
int*ptr1;
char*ptr2;
float*ptr3;
ptr1=newint;
ptr2=newchar;
ptr3=newfloat(2,0);
*ptr1=7;
*ptr2=’a’;
int*p=newint[8];
inti=2;
int*p1=newint[i][3][4]//为多维数组分配空间时,每一维的界值都不能省略
structcode
{
intn;
code*next;
};
code*pcode;
pcode=newcode;
pode→n=1;
pcode→next=NULL;
2.deleteOperator
单目运算符,其作用是释放new分配的存储空间,格式为:
delete指针名;//deleteptr3;deletepcode;
delate[]p;//释放P所指向的数组存储区
delete[大小]p;//释放p所指向的制定个数的连续单元
作业:
阅读有关C和C++书籍,理解本章所讲内容。
上机实验:
验证本章所讲内容。
ch2ClassesandObjects
本章介绍C++中最基础、最重要的概念,他们是OOP的实质和精华之一。
2.1DefiningaClass
改变
现实世界中,任何事物都可以从属性和行为两方面加以描述。
摸仿
计算机世界类=数据+函数
成员成员
修改
客观世界中的事物都可以从属性与行为两个方面来认识:
class是对客观世界中事物的模仿;
class是对一组具有相同属性和行为的对象的描述;
class可以说是一种类型;
object是类型的实例,object是一个变量。
2.1.1DefinitionofaClass
C++中,用datamembers来描述事物的properties/attributes,用functionmembers来描述事物的behaviors/methods.将两者encapsulate在一起就是一种abstractdatastructure—class,其定义格式如下:
class类型名
{
private:
私有成员声明//只有本类中的成员函数才可以访问
Public:
公有成员声明//外界的非成员函数也可以访问
};
x
函数y()
private:
私有成员
public:
f()
……
例:
定义一个统计某厂产品情况的类product,其特征为:
属性:
产品名称,产品型号,产品数量;
方法:
输出一个产品的特征(属性)。
classproduct
{
private:
//可以省略
char*pname;
char*pnod;
public:
voidpdput();
};
注:
(1)类成员的隐含访问权限(Accessauthority)是私有的;
(2)private和public出现的顺序不固定;
(3)关键字class可用struct代替,代替后的类称为结构体,C++中结构体也可以有成员函数(特殊的类),与class类型的