14.1 C++的特点
14.2 最简单的 C++程序
14.3 C++的输入输出
14.4 函数的重载
14.5 带缺省参数的函数
14.6 变量的引用类型 5
14.7 内置函数
14.8 作用域运算符
14.9 动态分配 /撤销内存的运算符 new和 delete
14.10 小结第 14章 C++对 C的扩充
14.1 C++的特点
C语言是结构化和模块化的语言,它是面向过程的。
在处理较小规模的程序时,程序员用 C语言较得心应手。但是当问题比较复杂、程序的规模比较大时,结构化程序设计方法就显出它的不足。 C程序的设计者必须细致地设计程序中的每一个细节,
准确地考虑到程序运行时每一时刻发生的事情,
例如各个变量的值是如何变化的,什么时候应该进行哪些输入,在屏幕上应该输出什么等。这对程序员的要求是比较高的,如果面对的是一个复杂问题,程序员往往感到力不从心。当初提出结构化程序设计方法的目的是解决软件设计危机,
但是这个目标并未完全实现。
为了解决软件设计危机,在 20世纪 80年代提出了面向对象的程序设计 (Object-Oriented
programming,简称 OOP),在这种形势下,C++
应运而生。 C++是由贝尔实验室的 Bjarne
Stroustrup博士及其同事在 C语言的基础上开发成功的。 C++保留了 C语言原有的所有优点,增加了面向对象的机制。 C++与 C完全兼容,用 C语言写的程序可以不加修改地用于 C++。从 C++名字可以看出它是对 C的扩充,是 C的超集。它既可以用于结构化程序设计,又可用于面向对象的程序设计,
因此它是一个功能强大的混合型的程序设计语言。
使用 C++必须事先安装 C++编译系统,在 DOS系统下可以使用 Turbo C++或 Borland C++。 C源程序的后缀一般为,c,而 C++的后缀一般为,cpp(为 C
plus plus的缩写,即 C++)。在 Borland C++开发环境中,既可以使用 C语言,也可以使用 C++语言。
它有两个编译系统,根据源程序文件名的后缀是,c
还是,cpp来决定使用哪个编译系统。
如上所述,面向对象程序设计方法主要是解决大型软件的设计问题。只有编写过大型程序的人才会体会到 C的不足和 C++的优点。 C++是一种大型语言,其功能、概念和语法规定都比较复杂,要深入掌握它需要花较多的时间,尤其是需要有较丰富的实践经验。用 C++编程的主要是软件专业人员。学校里一般专业的程序设计课程任务主要是进行程序设计的基本训练,因此,我们认为当前对大多数学生来说,应先掌握好 C语言程序设计。
有了 C语言的基础在需要时再学习 C++不会太困难。
为了使读者对 C++有初步的了解,以便为今后学习
C++打下基础,我们在进行本书的修订时特地增加了第 14章和第 15章,介绍 C++的初步知识。
C++对 C的“增强”,表现在两个方面:
(1) 在原来面向过程的机制基础上,对 C语言的功能做了不少扩充。
(2) 增加了面向对象的机制。
本章介绍 C++对 C功能的扩充。第 15章介绍有关面向对象的内容。
14.2 最简单的 C++程序
例 14.1 输出一行字符。
#include <stdio.h>
#include <iostream.h>
/* 本程序的作用是输出一行字符 */
void main( )
{
printf("This is a c++ program.\ n");
cout <<" This is a c++ program.\ n" ; //本行输出一行字符
}
本程序和以前见过的 C程序有什么不同?
(1) 在 C++程序中一般习惯在主函数 main前面加了一个类型声明符 void,表示 main函数没有返回值。
(2) 除了可以用 /*……*/ 形式的注释行外,还允许使用以 // 开头的注释。从程序最后一行中可以看到:
以 //开头的注释可以不单独占一行,它出现在语句之后。编译系统将 // 以后到本行末尾的所有字符都作为注释。应注意:它是单行注释,不能跨行。
C++的程序设计人员多愿意用这种注释方式,它比较灵活方便。
(3) 除了可以用 printf函数输出信息外,还可以用
cout进行输出。 cout要与运算符 <<配合使用,程序中 cout的作用是将 <<运算符右侧的内容送到输出设备中输出。
(4) 使用 cout需要用到头文件 iostream.h,在程序的第一行用 #include命令将该头文件“包含”进来。
程序运行时输出,This is a c++ program.
This is a c++ program.可以看到程序中最后两个语句的作用相同,都是输出 This is a c++ program.。
14.3 C++的输入输出
在 C语言中文件不是由记录构成的。对文件的存取是以字节为单位的,对一个 C文件的输入和输出是一个字节流。输入和输出的数据流的开始和结束只受程序控制而不受物理符号(如回车换行符)
的控制。这种文件称为流式文件。在输入操作中,
字节从输入设备流向内存,在输出操作中,字节从内存流向输出设备。 C++为了方便使用,除了可以利用 printf和 scanf函数进行输出和输入外,还增加了标准输入输出流 cout和 cin。 cout是由 c和 out两个单词组成的,代表 C++的输出流,cin是由 c和 in
两个单词组成的,代表 C++的输入流。它们是在头文件 iostream.h中定义的。在键盘和显示器上的输入输出称为标准输入输出,标准流是不需要打开和关闭文件即可直接操作的流式文件。
C++预定义的标准流如表 14.1所示。
表 14.1
流名 含义 隐含设备
cin 标准输入 键盘
cout 标准输出 屏幕
cerr 标准出错输出 屏幕
clog cerr的缓冲形式 屏幕
14.3.1 用 cout进行输出
cout必须和输出运算符 <<一起使用。 << 在这里不作为位运算的左移运算符,而是起插入的作用,
例如,cout<<"Hello!\n";的作用是将字符串
,Hello!\n” 插入到输出流 cout中,也就是输出在标准输出设备上。
也可以不用 \n控制换行,在头文件 iostream.h中定义了控制符 endl代表回车换行操作,作用与 \n相同。
endl的含义是 end of line,表示结束一行。
可以在一个输出语句中使用多个运算符 << 将多个输出项插入到输出流 cout中,<<运算符的结合方向为自左向右,因此各输出项按自左向右顺序插入到输出流中。例如:
for (i=1; i<=3;i++)
cout<<"count="<<i<<endl;
输出结果为,
count=1
count=2
count= 3
注意:每输出一项要用一个 << 符号。不能写成
cout<<a,b,c,"A"; 形式。
用 cout和 << 可以输出任何类型的数据,如:
float a=3.45;
int b=5;
char c=′A′;
cout<<"a="<<a<<","<<"b="<<b<<","<<"c="<<c<<endl;
输出结果为
a=3.45,b=5,c=A
可以看到在输出时并未指定数据的类型(如实型、
整型),系统会自动按数据的类型进行输出。这比用 printf函数方便,在 printf函数中要指定输出格式符(如 %d,%f,%c等)。
如果要指定输出所占的列数,可以用控制符 setw设置 (注意:若使用 setw,必须包含头文件 iomanip.h),
如 setw(5) 的作用是为其后面一个输出项预留 5列,
如输出项的长度不足 5列则数据向右对齐,若超过
5列则按实际长度输出。如将上面的输出语句改为:
cout<<"a="<<setw(6)<<a<<endl<<"b="<<setw(6)<<b<<en
dl<<"c="<<setw(6)<<c<<endl;
输出结果为
a=3.45
b=5
c=A
在 C++中将数据送到输出流称为“插入” (inserting),或“放到” (putting) 。 << 常称为“插入运算符”。
14.3.2 用 cin进行输入
输入流是指从输入设备向内存流动的数据流。标准输入流 cin是从键盘向内存流动的数据流。用 >> 运算符从输入设备键盘取得数据送到输入流 cin中,然后送到内存。在 C++中,这种输入操作称为“提取” (extracting) 或“得到” (getting) 。 >> 常称为“提取运算符”。
cin要与 >> 配合使用。例如:
int a;
float b;
cin>>a>>b; //输入一个整数和一个实数。注意不要写成 cin>>a,b;
可以从键盘输入,
20 32.45 (数据间以空格分隔)
a和 b分别获得值 20和 32.45。用 cin和 >> 输入数据同样不需要在本语句中指定数据类型(用 scanf函数输入时要根据数据类型指定输入格式符,如 %d,
%c等)。
例 14.2 cin与 cout一起使用。
#include <iostream.h>
void main( )
{cout<<"please enter your name and age:"<<endl;
char name[ 10] ;
int age;
cin>>name;
cin>>age;
cout<<"your name is "<<name<<endl;
cout<<"your age is "<< age<<endl;
}
运行情况如下:
please enter your name and age:
Wang-li↙
19 ↙
your name is Wang-li
your age is 19
程序中对变量的定义放在执行语句之后。 C语言是不允许这样的,它要求声明部分必须在执行语句之前。而 C++允许对变量的声明放在程序的任何位置(但必须在使用该变量之前)。这是 C++对 C限制的放宽。
C++为流输入输出提供了格式控制,如,dec(用十进制形式),hex(用十六进制形式),oct(用八进制形式),还可以控制实数的输出精度等。
14.4 函 数 的 重 载
在上一节用到了插入运算符 << 和提取运算符 >>。
这两个运算符本来是左移运算符和右移运算符,
现在把它作为输入输出运算符。即允许一个运算符用于不同场合,有不同的含义,这就叫运算符的“重载” (overloading),即重新赋予它新的含义。
其实就是“一物多用”。
函数也可以重载。用 C语言编程时,有时会发现有几个不同名的函数,实现的是同一类的操作。例如要求从 3个数中找出其中最大者,而这 3个数的类型事先不确定,可以是整数、实数或长整数。
程序设计者必须分别设计出 3个函数,其原型为:
int max1(int a,int b,int c);
(求 3个整数中的最大者)
float max2(float a,float b,float c);
(求 3个实数中的最大者)
long max3(long a,long b,long c);
(求 3个长整数中的最大者)
C语言规定在同一作用域(如同一文件模块中)中不能有同名的函数,因此 3个函数的名字不相同。
C++允许在同一作用域中用同一函数名定义多个函数,这些函数的参数个数和参数类型不同。这就是函数的重载,即一个函数名多用。
对上面的问题可以编写如下的 C++程序。
例 14.3 求 3个数中最大的数(分别考虑整数、实数、
长整数的情况)。
#include <iostream.h>
int max(int a,int b,int c) //求 3个整数中的最大者
{ if (b>a) a=b;
if (c>a) a=c;
return a; }
float max(float a,float b,float c) //求 3个实数中的最大者
{ if (b>a) a=b;
if (c>a) a=c;
return a; }
long max(long a,long b,long c) //求 3个长整数中的最大者
{ if (b>a) a=b;
if (c>a) a=c;
return a; } void main( )
{int a,b,c; float d,e,f; long g,h,i;
cin>>a>>b>>c; cin>>d>>e>>f; cin>>g>>h>>i;
int m;
m= max(a,b,c); //函数值为整型
cout <<"max-i="<<m<<endl;
float n;
n=max(d,e,f); //函数值为实型
cout<<"max-f="<<n<<endl;
long int p;
p=max(g,h,i); //函数值为长整型
cout<<"max-l="<<p<<endl;
}
运行情况如下:
85-6↙
56.990.76543.1↙
67543-56778123↙
max-i=8 ( 3个整数的最大值)
max-f=90.765 ( 3个实数的最大值)
max-l=78123 ( 3个长整数的最大值)
main函数 3次调用 max函数,每次实参的类型不同。
系统会根据实参的类型找到与之匹配的函数,然后调用该函数。
上例 3个 max函数的参数个数相同而类型不同。参数个数也可以不同,见下例。
例 14.4求 n个整数中的最大数。 n的值为 2和 3。
#include <iostream.h>
int max(int a,int b,int c) //求 3个整数中的最大者
{ if (b>a) a=b;
if (c>a) a=c;
return a; }
int max(int a,int b) //求两个整数中的最大者
{ if (a>b) return a;
else return b;}void main( )
{int a=7,b=-4,c=9;
cout<<max(a,b,c)<<endl; //输出 3个整数中的最大者
cout<<max(a,b)<<endl; //输出两个整数中的最大者
}
运行情况如下:
9
7
两次调用 max函数的参数个数不同,系统会根据参数的个数找到与之匹配的函数并调用它。
参数的个数和类型可以都不同。应当注意:重载函数的参数个数或类型必须至少有一者不同,函数返回值类型可以相同也可以不同。但不允许参数个数和类型都相同而只有返回值类型不同,因为系统无法从函数的调用形式上判断哪一个函数与之匹配。
14.5 带缺省参数的函数
一般情况下,实参个数应与形参个数相同。 C++允许实参个数与形参个数不同。办法是在形参表列中对一个或几个形参指定缺省值 (或称默认值 )。例如某一函数的首部可用如下形式:
void fun(int a,int b,int c=100)
在调用此函数时如写成 fun(2,4,6),则形参 a,b,
c的值分别为 2,4,6(这是与过去一样的)。如果写成 fun(2,4),即少写了最后一个参数,由于在函数定义时已指定了 c的缺省值为 100,因此 a,
b,c的值分别为 2,4,100。请注意:赋予缺省值的参数必须放在形参表列中的最右端。例如:
void f1(float a,int b,int c=0,char d=′a′) (正确 )
void f2(float a,int c=0,char d=′a′,int b) (不正确 )
利用这一特性,可以使函数的使用更加灵活。例如例 14.4求两个数或 3个数中的最大数。也可以不用重载函数,而将函数 max的首行写成
int max(int a,int b,int c=-32768)
如果只想从两个数中找大者,则可以在调用时写成 max(100,675),c的值自动取 -32768,由于 -
32768是最小整数,因此从 100,675,-32768中选大者和从 100,675中选大者的结果是一样的。
注意:不要同时使用重载函数和缺省参数的函数,
因为当调用函数时少写一个参数,系统无法判定是利用重载函数还是利用缺省参数的函数,会发生错误。
14.6 变量的引用类型
14.6.1 引用的概念
,引用” (reference)是 C++的一种新的变量类型,
是对 C的一个重要扩充。它的作用是为一个变量起一个别名。假如有一个变量 a,想给它起一个别名
b,可以这样写:
int a;
int &b=a;
这就声明了 b是 a的“引用”,即 a的别名。经过这样的声明后,使用 a或 b的作用相同,都代表同一变量。注意:在上述声明中,&是“引用声明符”,
并不代表地址。不要理解为“把 a的值赋给 b的地址”。
声明引用并不另开辟内存单元,b和 a都代表同一变量单元。在声明一个引用型变量时,必须同时使之初始化,即声明它代表哪一个变量。 在声明一个变量的引用后,在本函数执行期间,该引用一直与其代表的变量相联系,不能再作为其他变量的别名。下面的用法不对:
int a1,a2;
int &b=a1;
int &b=a2;(企图使 b变成 a2的引用(别名)是不行的 )
14.6.2 引用的简单使用
通过下面的例子可以了解引用的简单使用。
例 14.5 了解引用和变量的关系。
#include <iostream.h>
#include <iomanip.h>
void main( )
{int a=10;
int &b=a; //声明 b是 a的引用
a=a*a; //a的值变化了,b的值也应一起变化
cout<<a<<setw(6)<<b;
b=b/5; //b的值变化了,a的值也应一起变化
cout<<b<<setw(6)<<a;
}
a的值开始为 10,b是 a的引用,它的值当然也应该是 10,当 a的值变为 100( a*a的值)时,b的值也随之变为 100。在输出 a和 b的值后,b的值变为 20,
显然 a的值也应为 20(见图 14.1)。运行记录如下:
100 100
20 20
图 14.1
14.6.3 引用作为函数参数
有了变量名,为什么还需要一个别名呢? C++之所以增加“引用”,主要是把它作为函数参数,以扩充函数传递数据的功能。
在 C语言中,函数的参数传递有以下两种情况。
(1) 将变量名作为实参。这时传给形参的是变量的值。传递是单向的,在执行函数期间形参值发生变化并不传回给实参,因为在调用函数时,形参和实参不是同一个存储单元。下面的程序无法实现两个变量的值互换。
例 14.6 错误的程序。
#include <iostream.h>
void swap(int a,int b)
{int temp;
temp=a;
a=b;
b=temp; //实现 a和 b的值互换
}
void main( )
{int i=3,j=5;
swap(i,j);
cout<<i<<","<<j<<endl; //i和 j的值未互换
}
输出 i和 j的值仍为 3和 5。见图 14.2示意。图 14.2(a)
表示调用函数时的数据传递,图 14.2(b) 是执行
swap函数体后的情况,a和 b值的改变不会改变 i和 j
的值。
为了解决这个问题,在第 10章介绍了传递变量地址的方法。
图 14.2
(2) 传递变量的指针。使形参得到一个变量的地址,
这时形参指针变量指向实参变量单元。见例 14.7。
例 14.7 使用指针变量作形参,实现两个变量的值互换。
#include <iostream.h>
void swap(int *p1,int *p2)
{int temp;
temp=*p1;
*p1= *p2;
*p2=temp;
}
void main( )
{int i=3,j=5;
swap(&i,&j);
cout<<i<<","<<j<<endl;
}
形参与实参的结合见图 14.3示意。调用函数时把变量 i和 j的地址传送给形参 p1和 p2(它们是指针变量),因此 *p1和 i为同一内存单元,*p2和 j为同一内存单元,图 14.3(a) 表示刚调用 swap函数时的情况,图 14.3(b) 表示执行完函数体语句时的情况。
图 14.3
显然,i和 j的值改变了。
这种方法其实也是采用“值传递”方式,向一个指针变量传送一个地址。然后再通过指针变量访问有关变量。这样做能得到正确结果,但是在概念上“兜了一个圈子”,不那么直截了当。在
PASCAL语言中有“值形参”和“变量形参”
(即 var形参),对应两种不同的传递方式,前者采用值传递方式,后者采用地址传递方式(传送的是变量的地址而不是变量的值,使形参指向一个变量)。在 C语言中,只有“值形参”而无“变量形参”,全部采用值传递方式。 C++把引用型变量作为函数形参,就弥补了这个不足。
C++提供了向函数传递数据的第三种方法,即传送变量的别名。
例 14.8 利用“引用形参”实现两个变量的值互换。
#include <iostream.h>
void swap(int &a,int &b)
{int temp;
temp=a;
a=b;
b=temp;
}
void main( )
{int i=3,j=5;
swap(i,j);
cout<<"i="<<i<<" "<<"j="<<j<<endl;
}
输出结果为
i=5 j=3
在 swap函数的形参表列中声明变量 a和 b 是整型的引用变量(和其他变量一样,既可以在函数体中声明变量的类型,也可以在定义函数时在形参表列中声明变量的类型)。图 14.4请注意:在此处
&a不是,a的地址”,而是指,a是一个引用型变量”。 但是此时并未对它们初始化,即未指定它们是哪个变量的别名。当 main函数调用 swap函数时由实参把变量名传给形参。 i的名字传给引用变量 a,这样 a就成了 i的别名。同理,b成为 j的别名。
a和 i代表同一个变量,b和 j代表同一个变量。在
swap函数中使 a和 b的值对换,显然,i和 j的值同时改变了(见图 14.4示意,其中 (a)是刚开始执行
swap函数时的情况,(b)是执行完函数体语句时的情况)。在 main函数中输出 i和 j已改变了的值。
实际上,实参传给形参的是变量的地址,也就是使形参 a具有变量 i的地址,从而使 a和 i共享同一单元。为便于理解,我们说把变量 i的名字传给引用变量 a,使 a成为 i的别名。请注意这种传递方式和使用指针变量作形参时有什么不同?分析例 14.8
(对比例 14.7),可以发现:① 不必在 swap函数中设立指针变量,指针变量要另外开辟内存单元,
其内容是地址。而引用变量不是一个独立的变量,
不单独占内存单元,在本例中其值为一整数。②
在 main函数中调用 swap函数时实参不必在变量名前加 &以表示地址。这种传递方式相当于 PASCAL
语言中的“变量形参”,系统传送的是实参的地址而不是实参的值。显然,这种用法比使用指针变量简单、直观、方便。
当读者看到 &a这样的形式时,怎样区别是声明引用变量还是取地址的操作呢?请记住,当 &a的前面有类型符时(如 int &a),它必然是对引用的声明;如果前面无类型符(如 &a),则是取变量的地址。
14.7 内 置 函 数
调用函数时需要一定的时间,如果有的函数需要频繁使用,则所用时间会很长,从而降低程序的执行效率。 C++提供一种提高效率的方法,即在编译时将所调用函数的代码嵌入到主调函数中。这种嵌入到主调函数中的函数称为内置函数 (inline
function),又称内嵌函数。在有些书中把它译成
“内联函数”。
指定内置函数的方法很简单,只需在函数首行的左端加一个关键字 inline即可。
例 14.9 将函数指定为内置函数。
#include <iostream.h>
inline int max(int a,int b,int c) //这是一个内置函数,
求 3个整数中的最大者
{ if (b>a) a=b;
if (c>a) a=c;
return a;
}
void main( )
{int i=7,j=10,k=25,m ;
m=max(i,j,k);
cout<<"max="<<m<<endl;
}
由于在定义函数时指定它为内置函数,因此编译系统在遇到函数调用 max(i,j,k)时,就用 max函数体的代码代替 max(i,j,k),同时将实参代替形参。
这样,m=max(i,j,k)就被置换成
if(j>i) i=j;
if(k>i) i=k;
m=i;
内置函数与宏替换有些相似,但不完全相同。宏替换是在编译前由预处理程序进行预处理,它只作简单的字符替换而不作语法检查。而内置函数是在编译时处理的,编译程序能识别内置函数,
对它进行语法检查。有些问题既可以用宏来处理,
也可以用内置函数处理,显然,内置函数优于宏替换,它不会出现宏替换中可能产生的副作用。
使用内置函数可以节省运行时间,但却增加了目标程序的长度。假设要调用 10次 max函数,则在编译时先后 10次将 max的代码复制并插入 main函数,
大大增加了 main函数的长度。因此只用于规模很小而使用频繁的函数,可大大提高运行速度。
14.8 作用域运算符
每一个变量都有其有效的作用域,只能在变量的作用域内使用该变量,不能直接使用其他作用域中的变量。例如:
#include <iostream.h>
float a=13.5;
void main( )
{int a=5;
cout<<a;
}
程序中有两个 a变量:一个是全局变量 a,实型;
另一个是 main函数中的整型变量 a,它是在 main函数中有效的局部变量。根据规定,在 main函数中局部变量将屏蔽全局变量。因此用 cout输出的将是局部变量 a的值 5,而不是实型变量的值 13.5。如果想输出全局实型变量的值,有什么办法呢? C++提供作用域运算符 ∷,它能指定所需要的作用域。
可以把 main函数改为,
void main( )
{int a=5;
cout<<a<<endl;
cout<<∷ a<<endl;
}
运行时输出:
5(局部变量 a的值)
13.5 (全局变量 a的值)
∷ a表示全局作用域中的变量 a。请注意:不能用
∷ 访问函数中的局部变量。
14.9 动态分配 /撤销内存的运算符 new和 delete
在软件开发中,常常需要动态地分配和撤销内存空间。在第 11章中已知 C语言中是利用库函数 malloc和
free分配和撤销内存空间的。但是使用 malloc函数时必须指定需要开辟的内存空间的大小。其调用形式为 malloc(size) 。 size是字节数,需要人们事先求出或用 sizeof运算符由系统求出。此外,malloc函数只能从用户处知道应开辟空间的大小而不知道数据的类型,因此无法使其返回的指针指向具体的数据。
其返回值一律为 void *类型,必须在程序中进行强制类型转换,才能使其返回的指针指向具体的数据。
C++提供了较简便而功能较强的运算符 new和 delete
来取代 malloc和 free函数(为了与 C语言兼容,仍保留这两个函数)。例如:
new int; (开辟一个存放整数的空间,返回一个指向整型数据的指针)
new int(100); (开辟一个存放整数的空间,并指定该整数的初值为 100)
new char[ 10] ; (开辟一个存放字符数组的空间,
该数组有 10个元素,返回一个指向字符数据的指针)
new int[ 5][ 4] ; (开辟一个存放二维整型数组的空间,该数组大小为 5*4)
float *p=new float(3.14159) (开辟一个存放实数的空间,并指定该实数的初值为 3.14159,将返回的指向实型数据的指针赋给指针变量 p)
new运算符使用的一般格式为
new 类型 [初值]
用 new分配数组空间时不能指定初值。
delete运算符使用的一般格式为
delete [ ] 指针变量
例如要撤销上面用 new开辟的存放实数的空间 (上面第 5个例子 ),应该用
delete p;
前面用 new char[ 10] 开辟的空间,如果把返回的指针赋给了指针变量 pt,则应该用以下形式的
delete运算符撤销:
delete [ ] pt; (在指针变量前面加一对方括号,
表示对数组空间的操作)
例 14.10 开辟空间以存放一个结构体变量。
#include <string.h>
struct Student
{char name[ 10] ;
int num;
char sex;
};
void main ( )
{
Student *p;
p=new Student;
strcpy(p->name,"Wang Fun" );
p->num=10123;
p->sex=′M′;
delete p;
}
先声明了一个结构体类型 Student,定义一个指向它的指针变量 p,用 new开辟一段空间以存放一个
Student类型的变量,空间的大小由系统根据
Student自动算出,不必用户指定。执行 new返回一个指向 Student类型数据的指针,存放在 p中。然后对各成员赋值(通过指针变量 p访问结构体变量),最后用 delete撤销该空间。
如果由于内存不足等原因而无法正常分配空间,
则 new会返回一个空指针 NULL,用户可以根据该指针的值判断分配空间是否成功。
注意,new和 delete是运算符,不是函数,因此执行效率高。 malloc要和 free函数配合使用,new和
delete配合使用。不要混合使用 (例如用 malloc函数分配空间,用 delete撤销 ) 。
14.10 小结
在本章中介绍了在面向过程的机制基础上,C++对
C功能的扩展。它包括:
(1) 允许使用以 // 开头的注释。
(2) 对变量的定义出现在程序中的任何位置(但必须在引用该变量之前)。
(3) 提供了标准输入输出流 cin和 cout,它们不用指定输入输出格式符(如 %d),使输入输出更加方便。
(4) 可以利用函数重载实现用同一函数名代表功能类似的函数,以方便使用,提高可读性。
(5) 可以使用带缺省值的参数的函数,使函数的调用更加灵活。
(6) 提供变量的引用类型,即为变量提供一个别名,
将“引用”作为函数形参,可以实现通过函数的调用来改变实参变量的值。
(7) 增加了内置函数(内嵌函数),以提高程序的执行效率。
(8) 增加了单目的作用域运算符,这样在局部变量作用域内也能引用全局变量。
(9) 用 new和 delete运算符代替 malloc和 free函数,
使分配动态空间更加方便。
C++对 C的扩展还有其他一些。这些扩充使得人们使用结构化程序设计方法进行程序设计时,比以前更加方便和得心应手。有些人在编写小程序时,
利用 C++编写面向过程的程序,也取得很好的效果。