第二章
Sponsored Links
This presentation is the property of its rightful owner.
1 / 118

第二章 C++ 概述 PowerPoint PPT Presentation


  • 115 Views
  • Uploaded on
  • Presentation posted in: General

第二章 C++ 概述. 2.1 C++ 的起源和特点. 2.1.1 C++ 的起源 2.1.2 C++ 的特点: ( 1 ) C++ 保持与 C 兼容,许多 c 程序不经修改就可以被 C++ 所用。 ( 2 )软件的可重用性和可维护性好。 ( 3 )支持面向对象机制,可方便的模拟现实问题的实体。 (4)c++ 编写的程序可读性更好,代码结构更合理。 (5) 程序运行效率更高。. 1. 2.2 C++ 源程序的构成 2.2.1 C++ 程序的一般格式 class student{

Download Presentation

第二章 C++ 概述

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


第二章 C++概述


2.1 C++的起源和特点

2.1.1 C++的起源

2.1.2

C++的特点:

(1) C++保持与C兼容,许多c程序不经修改就可以被C++所用。

(2)软件的可重用性和可维护性好。

(3)支持面向对象机制,可方便的模拟现实问题的实体。

(4)c++编写的程序可读性更好,代码结构更合理。

(5)程序运行效率更高。

1


2.2 C++源程序的构成

2.2.1 C++程序的一般格式

class student{

private: int number;

char name[10];

int age;

float score;

public: void printname( ){cout<<name;}

void printage( ){cout<<age;}

void printheight( ){cout<<score;}

};

main( )

{ student s1;

s1.printname( );

}

4


C++程序的退化格式说明C++构造的示例程序

#include <iostream.h> // 系统头文件

int add(int a, int b); //函数原型的说明

int main( ) //主函数

{ int x,y,sum; //定义三个整型变量

cout<<"输入二个数:"<<'\n'; //界面:提示用户输入二个数

cin>>x; //从键盘输入变量x的值

cin>>y; //从键盘输入变量y的值

sum=add(x,y); //调用函数add,将函数返回值赋sum

cout<<"二数和是:"<<sum<<'\n'; //输出

return 0;

}

int add(int a, int b) //定义函数add,函数(返回)值为整型

{ int c; //定义临时变量c

c=a+b; //求和

return c; } //将c的值返回,通过add带回调用处

2


2.3 C++在非面向对象方面的一些特性

2.3.1 注释行

/* */ C的注释

// <CR> C ++的注释

注意:/*…*/方式的注释不能嵌套,

/*this is a multiline /*inside of */ here is the end*/错误

但//和/* */方式的注释可以互相嵌套。

/*this is a multiline//inside of which

here is the end*/

//this is a multiline/*inside of which*/


2.3.2 新的I/O流

cin是标准输入流,在程序中代表标准输入设备,即键盘。

cin>>表达式>>表达式 int x,y; cin>>x>>y;

cout是标准输出流,在程序中代表标准输出设备,即屏幕。

cout<<表达式<<表达式 cout<<“the result”<<x<<y;

使用cin或cout进行I/O操作时,在程序中必须嵌入头文件iostream.h

//例2.2

#include <iostream.h>

int main( )

{ char name[20];

cout<<"Hello, your name:";

cin>>name;

cout<<name<<endl;

return 0;

}

//例2.3

#include <iostream.h>

void main( )

{ int x=25;

cout<<hex<<x<<‘\n'<<dec<<x

<<‘\n‘<<oct<<x<<endl;

}

4


2.3.3 灵活的局部变量说明

int f( )

{ int i;

int j;

i=10;

j=25;

}

int f( )

{ int i;

i=10;

int j;

j=25;

for(int k=5;k>=0;k--) …..

…….

}

以上的写法在C++程序中都是正确的。


2.3.4 结构、联合和枚举名可直接作为类型名

定义枚举类型名:

enum bool {FALSE, TRUE};

定义结构类型名:

struct student {

int sno;

char *sneme;

};

C语言中定义枚举类型变量: enum bool done;

定义结构类型变量: struct student s1, s2;

C++语言中定义枚举类型变量: bool done;

定义结构类型变量: student s1, s2;


2.3.5 const修饰符

#define LIMIT 100

这里 LIMIT 是一个标志,代表 100

const 类型名 常量名=常数;

类型名 const 常量名=常数;

const int LIMIT=100; // const LIMIT=100;

int const LIMIT=100;// const LIMIT=100;

这里 LIMIT 是一个常量名,在内存空间放了100,因此有地址,可以用指针指向这空间,但不能修改它。


#include <iostream.h>

main( )

{ int a=1;

#define T1 a+a

#define T2 T1-T1

cout<<"T2 is "<<T2<<endl;

//cout<<“T2 is “<<T1-T1<<endl;

//cout<<“T2 is”<<a+a-a+a<<endl;

return 0;

}

#include <iostream.h>

main( )

{ int a=1;

const T1=a+a;

const T2=T1-T1;

cout<<"T2 is "<<T2<<endl;

return 0;

}

8


a

const 可以和指针一起使用,他们的组合可归纳为三种。

(1) 可以用一个指向常量的指针变量指向常量:

const char *name=“chen”;

name[3]=‘a’; //错误

name=“zhang”;//正确

(2)指针常量指向变量

char *const name=“chen”;

name[3]=‘a’; //正确

name=“zhang”; //错误

(3)常指针指向常量

const char *const name =“chen”;

常量

chen

n

name

常量

zhang

name

chen

n

a

a

常量

zhang


说明:

(1)常量也可以用变量初始化。

const 类型名 常量名=变量名;

float a=3.4;

const float b=a;a=4.5;cout<<b;

常量在其有效的范围内不能再赋值。而变量可以多次赋值。

(2)常量一旦初始化,在其作用域内都不能修改。

#include<iostream.h>

void f( )

{const a=100;

cout<<a;

}

void main( )

{float a;

a=3.3;

cout<<a;

f( );

}


(3)常量可以作为函数参数。

int f ( const int k)

{const int j=k*k;

cout<<k;

return j;

}

void main( )

{cout<<f(3);}

void t(const int i)

{++i; //error}


float circle(float r)

{ return 3.1416*r*r; }

2.3.6 内置函数

inline float circle(float r)

{ return 3.1416*r*r; }

#include <iostream.h>

int main( )

{ for(int i=1;i<=3;i++)

cout<<"r="<<i<<" area="<<circle(i)<<endl;

return 0;}

在函数前加以 inline ,成为内置函数

#include <iostream.h>

int main( ) 代码嵌入

{ for(int i=1;i<=3;i++)

cout<<"r="<<i<<" area="<<circle(i)<<endl;

return 0;

}

优点1:可以消除函数调用时的系统开销,以提高运行的速度。

3.1416*r*r

9


//例2.7

#include <iostream.h>

#define doub(x) x*2

int main( )

{ for(int i=1;i<=3;i++)

cout<<doub(i)<<endl;

cout<<doub(1+2)<<endl;

return 0;

}

//例2.8

#include <iostream.h>

inline int doub(int x)

{ return x*2; }

int main( )

{ for(int i=1;i<=3;i++)

cout<<doub(i)<<endl;

cout<<doub(1+2)<<endl;

return 0;

} 优点2:可以消除宏定义的不安全性

1

4

6

5

1

4

6

6

1+2*2

10


注意:

① 内联函数体内一般不能有循环语句和switch语句。

② 内联函数的定义必须出现在第一次被调用之前.

inline float circle(float r)

{ return 3.1416*r*r; }

int main( )

{ for(int i=1;i<=3;i++)

cout<<"r="<<i<<" area="<<circle(i)<<endl;

return 0;

}

③只有很简单而使用频率很高的函数才被说明为内联函数。


2.3.7 函数原型

返回类型 函数名(参数表);

//例2.9

#include <iostream.h>

void write(char *s); //函数原型或叫函数申明

void main( )

{ write("Hello, world!"); }

void write(char *s)无分号

{ cout<<s<<endl; }

。。。。。。。。。。。。

#include <iostream.h>

void write(char *s)

{ cout<<s<<endl; }

void main( )

{ write("Hello, world!"); }

11


说明:

(1)函数原型的参数表中可不包含参数的名字,而只包含参数的类型,但函数头中必须给出参数的名字。

如:int cal(int ,int);

int main( )

{ … }

int cal(int a,int b)

{return a*b;}

(2)如果函数原型中没有任何参数,则C++假定参数表为空(void)

int cal( );等价于

int cal(void);


(3)函数头中没有指出返回类型的函数(包括主函数),C++默认该函数的返回类型为int。

cal(int a,int b){…} 等价于int cal(int a,int b){…}

main( )

{…

return 0;}

(4)如果一个函数没有返回值,则必须在函数名前注明返回类型为void。

void cal( ){cout<<“good”;}

void main( ){ }


#include <iostream.h>

void main()

{

int m,n,l,s;

int maxj(int a, int b);

int minb(int a, int b);

cout<<"输入2个正整数:";

cin>>m>>n;

if (m>0 && n>0) {

l=maxj(m,n);

s=minb(m,n);

cout<<i<<endl;

cout<<s<<endl;

}

else cout<<"输入了负数!\n";

return;

}

  • int maxj(int a, int b)

  • { int r,t;

  • if(a<b) {t=a;a=b;b=t;}

  • r=a%b;

  • while(r!=0){

    • a=b; b=r;

    • r=a%b;

  • }

  • return b;

  • }//最大公约数

  • int minb(int a, int b)

  • { int r;

  • r=maxj(a,b);

  • if (r!=0)

  • return a*b/r;

  • else

    • return 0;

  • }//最小公倍数

33


2.3.8 带有缺省参数的函数

C++在说明函数原型时,可以为一个或多个参数指定缺省参数值,以后调用此函数时,若省略其中某一实参,C++自动以缺省值作为相应參数的值。

#include<iostream.h>

void special(int x=5, float y=5.3);

void main( )

{special( );//第一次

special(25);//第二次

special(100,79.8);//第三次

}

void special(int x,float y)

{cout<<x*y;

}

12


#include<iostream.h>

void special(int x=5, float y=5.3)

{cout<<x*y;

}

void main( )

{special( );

special(25);

special(100,79.8);

}


说明:

(1)所有取缺省值参数都必须出现在不取缺省值参数的右边。

int fun(int i,int j=5, int k); 是错误的

int fun(int i, int k,int j=5); 是正确的

int fun(int i, int k=4,int j=5); 是正确的

(2)调用时,若某个参数省略,则其后的参数皆应省略。

int fun(int i=1, int k=4,int j=5){cout<<i*k*j;}

fun(2,3);

fun(2);

不合法的调用;

fun(, 3, 5);

fim(, 3);


(3)在相同的作用域内,默认形参值的说明应保持唯一。但如果在不同的作用域内,允许说明不同的默认形参。

add(int x=2,int y=5); //全局默认形参值

void main( )

{ add(int x=1,int y=9); //局部默认形参值

add( );

//此处调用时,采用局部默认形参值,x取值1,y取值9

}

void func( )

{add( ) ;

//此处调用时,采用全局默认形参值,x取值2,y取值5

}

add(int x,int y){cout<<x+y;}


2.3.9 函数重载

在C语言中,函数名必须是唯一的,例如:当要求编写求整数、浮点数和双精度度数的二次方的函数时,必须编写三个函数名不同的函数。

int isquare(int i)

{ return i*i; }

float fsquare(float f)

{ return f*f; }

double dsquare(double d)

{ return d*d; }

C++中,只要函数的參数的类型不同,或者參数个数不同,或者二兼有之,几个函数可以用相同的函数名,称为函数重载.使函数方便使用,便于记忆,也使程序设计更加灵活。

13


//**例2.10

#include <iostream.h>

int square(int i)

{ return i*i; }

float square(float f)

{ return f*f; }

double square(double d)

{ return d*d; }

void main( )

{ int i=12;

float f=3.4;

double d=5.67;

cout<<i<<'*'<<i<<'='<<square(i)<<endl;

cout<<f<<'*'<<f<<'='<<square(f)<<endl;

cout<<d<<'*'<<d<<'='<<square(d)<<endl;

}


//**例2.11

#include <iostream.h>

int mul(int x, int y)

{ return x*y; }

int mul(int x, int y, int z)

{ return x*y*z; }

void main( )

{ int a=3,b=4,c=5;

cout<<a<<'*'<<b<<'='<<mul(a,b)<<endl;

cout<<a<<'*'<<b<<'*'<<c<<'='<<mul(a,b,c)<<endl;

}

14


说明:

(1)重载函数应在参数个数或参数类型上有所不同,编译才能识别调用哪一个重载版本,即使返回类型不同也不行

如:int mul(int x, int y) ;和 double mul(int x, int y); 是不能重载的。

(2)一般而言,重载函数应对不同的参数情况执行相同的功能。

如:abs(int x); 和 abs(float x);都是求绝对值,一个是整数的绝对值,一个是实数的。

(3)函数的重载与带默认值的函数一起使用时,有可能引起二义性。

int mul(int x, int y)

{ return x*y; }

int mul(int x, int y, int z=5)

{ return x*y*z; }

当调用mul(3,4)时,编译程序无法确定使用哪个函数。


2.3.10 作用域运算符::

当全局变量和局部变量同名时,函数中不能使用全局变量。

//**例2.12

#include <iostream.h>

int avar=10; //全局变量

void main( )

{ int avar=25; //局部变量

cout<<"avar is "<<avar<<endl;

{float avar=4.5;

cout<<avar;

}

}

15


可用作用域运算符 :: //**例2.13

#include <iostream.h>

int avar;

void main( )

{ int avar;

avar=25; //局部变量avar

::avar=10; //全局变量avar

cout<<"local avar = "<<avar<<endl;

cout<<"global avar = "<<::avar<<endl;

}


a

4字节

ch

i

f

2.3.11 无名联合

C语言的共用体:

union data

{ int i;

char ch;

float f;

}

共享同一内存地址,分配的地址空间的大小是按照最大的来进行分配的

union data a;

引用:a.i =3; a.ch =‘k’; a.f =7.9; 等

16


a

4字节

ch

i

f

无名共用体如下:   union

{ int i;

char ch;

float f;

}

以后在程序中任何地方都可以使用i,ch,f,而不需要声明,因为无名共用体已经分配好空间。  

#include   <iostream.h>

void   main(void)  

{     union

{ int i;

char ch;

float f;

};

  i  =   12;     cout<<i;

f=6.5;

cout<<f;

  }  


2.3.12 强制类型转换

隐式类型转换是系统自动实行的转换,主要出现在赋值语句和表达式语句中。

int a=3.45;

float b=4;

double c=a+b;


C语言的强制类型转换: (类型标识符)表达式

int i=10;

float x=(float)i; int y=(int)(3+6.4)

C++的强制类型转换:

int i=10;

float x=float (i);

float y=(float) i;

两种方法C++都可以。

17


  • 2.3.13 new和delete

  • 动态内存分配是相对于静态内存分配而言的。

  • 静态内存分配是指在编译阶段就分配好存储单元空间,这些空间的大小在程序运行过程中是不可更改的,如变量、数组等; int i;

  • 动态内存分配则是指程序员在程序语句中通过调用内存分配函数或使用内存分配运算符取得存储空间,通过动态内存分配得到的空间的大小,编译器是不知道的,完全由动态运行中的程序的当时情况决定。


p

C语言用函数malloc( )和free( )动态分配内存和释放动态分配的内存。C++使用运算符new和delete能更好、更简单地进行内存的分配和释放。

如C语言中用:

int *p;

p=(int *) malloc ( sizeof(int) );

*p=10;

free(p);

18


而C++语言中

new运算符用于动态分配一块内存空间。new运算符的使用形式如下:

指针变量=new<数据类型>[长度]

char*CBuffer;

CBuffer=new char[256];

//分配一个可以容纳256个char型数据的空间

如果分配的空间长度为1个单位,则可以省略new运算符格式中的中括号和中括号中的整数。

float* pNum=new float;

与float* pNum=new float[1];等价。


//**2.14

#include <iostream.h>

void main( )

{ int *p; //定义一个整型指针变量p

p=new int;

*p=10;

cout<<*p<<endl;

delete p; //释放p指的空间,撤消指针p

}


说明:

(1)使用new运算符分配内存空间时,其空间长度可以是变量,也可以是数值表达式。例如:

int nSize=5;

int* nPInt=new int[nSize+5];

//分配一个可以容纳10个int型数据的空间

(2)使用new可以为数组动态分配内存空间。

int *pi=new int[10];

int *pi=new int[2][3][4];

由new分配的内存空间是连续的,可以通过指针的变化访问所分配空间的每一个元素。

int*nPInt=new int[10];

nPInt[5]=100;

*(nPInt+5)=100;

19


(3)new可在为简单变量分配内存空间的同时,进行初始化。

//**例2.15

#include <iostream.h>

void main( )

{ int *p;

p=new int(99); //动态分配内存,并将99作为初始值赋给它

cout<<*p<<endl;

delete p;

}


(4)由new运算符分配的内存空间在使用完毕后,应该使用delete运算符释放。如果应用程序对有限的内存是只取不还,系统很快就会因为内存枯竭而崩溃。

释放动态分配的数组存储区时,用如下格式:

delete 指针 及 delete[ ]指针

int*pInt=new int;

delete pInt;

int* pManyInt=new int[10];

delete[ ]pManyInt;

用new运算符获得的内存空间,只许使用一次delete,不允许多次对同一块空间进行多次释放,否则将会产生严重错误。


(5)使用动态分配内存时,如果没有足够的内存满足分配要求,则分配失败,将返回空指针(NULL)。

因此通常要对内存的动态分配是否成功进行检查。

分配内存失败,p=NULL

//**例2.16

#include <iostream.h>

void main( )

{ int *p;

p=new int;

if(!p) //if (p==NULL) 若分配内存失败

{ cout<<"allocation failure\n";

return ;

}

*p=20;

cout<<*p<<endl;

delete p;

}

p NULL

20


2.3.14 引用

引用简单的说就是别名,主要有变量的引用、函数參数的引用、函数返回值的引用。

1.引用变量

引用变量的声明形式为

<类型标识符> &引用名=变量名

int someInt; int& rInt=someInt

21


6

someint

rint

#include<iostream.h>

void main( )

{int someInt;

int& rInt=someInt;

cout<<&someInt<<““<<&rInt<<endl;

someInt=6;

cout<<"someInt:"<<someInt<<endl;

cout<<"rInt:"<<rInt<<endl;

rInt=7;

cout<<"someInt:"<<someInt<<endl;

cout<<"rInt:"<<rInt<<endl;

}

程序运行结果为

0xfff8 0xfff8

someInt:6

rInt:6

someInt:7

rInt:7


(1)在声明变量的引用时,必须立即对它进行初始化,不能以后再赋值。

int i; int &j; j=i; //错误

int &j=i;

引用的初始值可以为变量,也可以为另一个引用。

int i; int &j=i; int &k=j; //i有两个别名


(2) 定义完引用后,每次使用引用,可以直接通过引用名访问变量,而如果用指针,必须通过*间接访问变量。

#include <iostream.h>

void main( )

{ int i=15; //整型变量i

int *iptr=&i; //iptr指向i

int &rptr=i; //rptr引用i

cout<<"i is "<<i<<endl;

cout<<"*iptr is "<<*iptr<<endl;

cout<<"rptr is "<<rptr<<endl;

i=29;

cout<<" After changing i to 29"<<endl;

cout<<"i is "<<i<<endl;

cout<<"*iptr is "<<*iptr<<endl;

cout<<"rptr is "<<rptr<<endl;

}

i

iptr

rptr

22


(3)引用不可重新赋值,不可使其作为另一个变量的别名。

int i, k;

int &j=i;

j=&k; //错误

(4)并不是任何类型的数据都可以引用,下列都是错误的。

<1>不允许对空类型引用 void &a=10;

<2>不能建立引用数组 int a[3]; int &r[3]=a;

<3>不能建立指向引用的指针,不能建立引用的引用

int a;

int &*p=a;

int &&r=a;

23


(5)当使用取地址运算符时&,取的是被引用变量的地址。

int num=50;

int &ref=num;

int *p=&ref;

则p中保存的是变量num的地址。


2. 引用作为函数的參数

<1>值传递方式

#include <iostream.h>

void swap(int m, int n)

{ int temp;

temp=m;

m=n;

n=temp;

}

main( )

{ int a=5,b=10;

cout<<"a="<<a<<" b="<<b<<endl;

swap(a,b);

cout<<"a="<<a<<" b="<<b<<endl;

return 0;

}

a=5 b=10

a=5 b=10

a

m

b

n

tem

a

b

25


<2>地址传递调用的方式

#include <iostream.h>

void swap(int *m, int *n)

{ int temp;

temp=*m;

*m=*n;

*n=temp;

}

void main( )

{ int a=5,b=10;

cout<<"a="<<a<<" b="<<b<<endl;

swap(&a,&b);

cout<<"a="<<a<<" b="<<b<<endl;

}

a=5 b=10

a=10 b=5

a

m &a

temp

b

n &b

24


在以数组名作参数时,采取的也是地址传送方式。

float fun(float x[4])

{float sum=0,aver;

for(int i=0;i<4;i++)

sum=sum+x[i];

aver=sum/4;

}

void main( )

{float y[4]={3.5, 5.6, 4, 4.7};

float ave=fun(y);

return ;

}


<3>引用传递方式

#include <iostream.h>

void swap(int &m, int &n)

{ int temp;

temp=m;

m=n;

n=temp;

}

main( )

{ int a=5,b=10;

cout<<"a="<<a<<" b="<<b<<endl;

swap(a,b);

cout<<"a="<<a<<" b="<<b<<endl;

return 0;

}

a=5 b=10

a=10 b=5

a

m

b

n

temp

25


1、编写将字符串反序的函数,然后在主函数中调用该函数。

2、编写并验证名为sphere( )的函数,使其在给定一个球体的半径r之后能返回该球体的体积和表面积。

void sphere(float &a,float &v,float r)

a=4*pi*r*r; v=4/3*pi*r*r*r


a[254]

a[0]

a[1]

a

a

b

c

d

e

f

\0

b

b[0]

b[1]

#include <iostream.h>

#include<stdio.h>

#include <string.h>

void convert(char b[])

{ int l,i;

char c;

l=strlen(b);

for(i=0; i<=l/2 ;i++){

c=b[i];

b[i]=b[l-i-1];

b[l-i-1]=c;}

return ;

}

void main()

{ char a[255];

cout<<“输入字符串: \n";

gets(a); //cin>>a;?

convert(a);

cout<<“字符串反序为: \n";

puts(a);

return;

}

34


#define PI 3.14

#include<iostream.h>

void sphere(float &a,float &v,float r)

{a=4*PI*r*r;

v=4/3*PI*r*r*r;

}

void main( )

{float rad,area,vol;

cin>>r;

sphere(area,vol,rad);

cout<<area<<endl<<vol<<endl;

}

当通过一个函数调用返回多个值时,可以采用引用

调用。


3、引用作为返回值

  要以引用返回函数值,则函数定义时要按以下格式:

类型标识符 &函数名(形参列表及类型说明){函数体}

  说明:

  (1)以引用返回函数值,定义函数时需要在函数名前加&

  (2)用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。


void main( )

{double b1=f1(3.4);

double b2=f2(3.4);

}

  • double temp;double f1(double a){ temp=a*a; return temp;}double &f2(double a){ temp=a*a; return temp;}第一种情况是普通的返回方式,函数f1返回全局变量temp,是先将temp的值赋值给那个无名临时变量(该无名临时变量有return 语句产生),回到主函数后,赋值语句再把临时变量的值赋给所要的,无名临时变量生命期结束。第二种情况是引用返回方式,没有使用那个无名临时变量过渡,而是直接返回temp本身,赋给所要的。无名临时变量中放的是temp的地址。不产生拷贝,提高了效率。


引用作为返回值

函数可返回一个引用,其目的是可将函数用在赋值运算符的左边。

#include <iostream.h>

int a[]={1,3,5,7,9};

int &index(int); //声明返回引用的函数

void main( )

{ index(2)=25; //将a[2]重新赋值为25

for(int i=0;i<5;i++)

cout<<a[i]<<endl;

}

int &index(int i)

{ return a[i]; }

说明:不要返回对该函数内的局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成了“无所指”的引用,程序会进入未知状态。

int &f( )

{int a=1;

return a;}

int &f(int a )

{…

return a;}

26


引用作为返回值,有以下好处:

· 函数返回的是所返回的变量或对象本身,而不需要建立临时的对象。这样减少 了程序运行的开销;

· 返回一个引用使得一个函数调用的表达式可以成为一个左值表达式,可以为其 赋值。


4. 引用举例

#include <iostream.h>

int &max(int &num1, int &num2);

int &min(int &num1, int &num2);

void main( )

{ int num1, num2;

cin>>num1>>num2;

max(num1,num2)=0;

cout<<"\n把大的数置成 0 后, 这两个数是:";

cout<<'\n'<<num1<<" 和 "<<num2<<'\n';

cout<<"\n再一次输入二个数:\n";

cout<<"输入第一个数:";

cin>>num1;

cout<<"输入第二个数:";

cin>>num2;

min(num1,num2)=0;

cout<<"\n把小的数置成 0 后, 这两个数是:”;

cout<<'\n'<<num1<<" 和 "<<num2<<'\n’;

}

27


int &max(int &num1, int &num2) //两数中找大数

{ return (num1>num2)?num1:num2; }

int &min(int &num1, int &num2) //两数中找小数

{ return (num1<num2)?num1:num2; }

运行结果:

45 78

把大的数置成 0 后, 这两个数是:

45 和 0

再一次输入二个数:

输入第一个数: 13

输入第二个数: 56

把小的数置成 0 后, 这两个数是:

0 和 56

28


1、指针的概念

2、指针型变量的声明

<类型标识符>*指针变量名

int *p;

//p是用来保存一个指向int型变量的地址的指针型变量

char*pp[5];

//用来保存5个指向char型变量的指针的指针型变量数组

3、指针的基本操作

与指针有关的基本运算符有以下两个

(1)&变量名。“&”为取地址运算符,用来获取变量的首地址。 int i=5,*phint; phint=&i:

(2)*指针变量名。“*”为指向运算符,用来获取指针变量所指向变量的值。 i=*phint;


指针变量的使用例题。

#include<iostream.h>

void main()

{int m,n,*p1=&m,*p2=&n,*phint=NULL;

m=n=6;

cout<<"*p1="<<*p1<<",*p2="<<*p2<<endl;

cout<<"p1="<<p1<<",p2="<<p2<<endl;

cout<<"m="<<m<<",n="<<n<<endl;

cout<<"phint="<<phint<<endl;

*p1+=3;

p2=p1;

*p2*=4;

phint=p2;

cout<<"*p1="<<*p1<<",*p2="<<*p2<<endl;

cout<<"p1="<<p1<<",p2="<<p2<<endl;

cout<<"m="<<m<<",n="<<n<<endl;

cout<<"phint="<<phint<<endl;

} //假设&m=0x0012FF7C,&n=0x0012FF78


程序运行结果为

*p1=6,*p2=6

p1=0x0012FF7C,p2=0x0012FF78

m=6,n=6

pjint=0x00000000

*p1=36,*p2=36

p1=0x0012FF7C,p2=0x0012FF7C

m=36,n=6

pjint=0x0012FF7C


4、指针的运算

对指针也可以进行赋值、算术和关系运算。

(1)指针的赋值运算

对于普通变量的赋值运算,即使变量类型与值的类型不同,赋值运算也是允许的,只不过这种赋值会遵循某些转换规则进行。

int n; char Ch='A'; n=Ch;

而指针型变量在赋值时,决不允许将与指针型变量类型不同的指针值赋予指针变量。

int* pnValue;

char byCh='A';

pnVaIue=&byCb;

是不允许的,因为&byCh的类型是char*,而pnValue的类型是int*。

但int* pnVa1ue; char byCh='A'; pnValue=(int*)&byCh;

是可以的


(2)对于非void*型的指针型变量,只能进行加一个整数、减一个整数和两个指针变量相减三种运算。void*型指针变量不能做任何算术运算。

int nValue;

int*p1=&nValue;

p1=p1+1; //p1++;

假设p1的初始地址是2000,则进行p1=p1+1;运算后,p1的地址值是2002.

int *p1, *p2;//p1 p2值分别为2000 2006

p2-p1=3


(3)指针间也可以进行关系运算。关系运算符>、<、=、>=、<=、!=可以用来连接两个指针型变量做关系运算。指针间的关系运算结果就是两个指针所指的地址值的大小的关系运算结果。

两个进行关系运算的指针一般要求是同一类型的指针。


2.3.15void 型指针

void指针是一个特殊指针,可以说是任意指针,因为任何类型的指针值都可以赋给void类型的指针

void main( )

{ void *vp; int i=5; float f=7.8; char c='A';

int *ip; float *fp; char *cp;

ip=&i; vp=&i;

cp=&c; vp=&c;

fp=&f; vp=&f;

vp=ip; vp=fp; vp=cp;

ip=vp; cp=vp; fp=vp; //错误

}


void   指针是空类型指针,它不指向任何类型,只是一个地址.当进行自增运算或取指针指向的值时就会出错,空指针也不能用--->运算符号。要想使用指向操作必须进行显示类型转换。

void main( )

{ float b=3.4;     void  * p=&b;     p++ ;  //error;

(float*)p++;  //error  *p=20.5   //error;       *(float *)p=20.5;  int   a=1;     int *ps=&a;     p=ps;  ps=p; //error     ps=(int*)p;

}


通过指针引用数组元素

由于指针同数组的特殊关系,数组与指针几乎可以互换使用。下面利用一个具体例子来说明通过指针引用数组元素的方法。

用指针的方法编写求一个数组中所有元素之和的程序。


#include<iostream.h>

void main( )

{int Array[10]={6,7,8,9,5,4,3,2,10,1};

int sum=0,*p=Array;

for(i=0;i<10;i++)

sum=sum+(*p++);

//sum=sum+*p; p++;

cout<<"数组各元素和:sum1="<<sum<<endl;

}


指针和函数

指针变量可以作函数的参数,指针也可作函数的返回值,还有一种指针可以用来指向函数


指向函数的指针

1.指向函数指针变量的定义与使用

同数据一样,程序也保存在内存中,函数在内存中的起始地址称为入口地址,在调用函数时,只需知道被调函数的入口地址,即函数的指针就可以调用函数。

函数名就是一个指针,它指向函数的入口,我们可以定义一个指针变量,并赋予它函数名值,这样的指针变量成为指向函数的指针变量。

声明一个函数指针变量的形式如下:

<类型标识符>(*函数指针变量名)(参数表)

注意,定义中的两对圆括号都不要遗漏,数据类型是函数指针变量所指函数的返回值的数据类型。


例如,若定义函数

void FunctionA(int m,int n);

则对应于函数FunctionA的指针型变量可以按如下方法声明:

void(*pFPointer)(int,int);

要用已经定义的函数指针变量来调用函数,需要分两步进行。

第一步:将函数名赋给已定义的函数指针变量。采用的格式为

函数指针变量名=函数名


例如,可以将FunctionA的入口地址值赋予pFPointer这个函数指针变量:

pFpointer=FunctionA;

第二步:使用函数指针变量调用它所指的函数。采用的格式为

(*函数指针变量名)(实参表)或

函数指针变量名(实参表)

事实上,由于pFPointer和FunctionA指向同一函数入口,除了可以使用函数名FunctionA调用函数外,当然可以使用函数指针pFPointer调用函数。例如:

FunctionA(3,4) 等价于

(*pFPointer)(3,4);或pFPointer(3,4);


#include<iostream.h>

void FunctionA(int m,int n)

{cout<<m*n;}

void main( )

{void(*p)(int,int);

p=FunctionA;

(*p)(3,4);//p(3,4)

}


2.函数指针变量作为函数的参数

函数指针变量的一个主要用途是在函数调用时把函数指针变量作为参数,也就是说传递的不是数值,而是函数的入口地址,目的是实现对若干个不同函数的灵活调用。具体编程时要注意的是:主调函数的实参应设置成将被调用的函数名,被调函数的相应形参应设置成接受同类型函数入口地址的函数指针变量。


void main( )

{int a=5,b=10;

cin>>a>>b;

cout<<"a+b="<<

funct(add,a,b)<<endl;

cout<<"a-b="<<

funct(sub,a,b)<<endl;

}

#include<iostream.h>

int add(int x,int y)

{return x+y;}

int sub(int x,int y)

{return x-y;}

int funct(int(*fun)(int,int),int x,int y)

{int result;

result=(*fun)(x,y);

//等价于result=fun(x,y);

return result;

}


指针作为函数的返回类型

如前所述,函数的数据类型是指函数返回值的类型,它可以是整型、字符型、浮点型或void(无返回值),也可以是指针类型,即函数的返回值是地址。返回值是地址的函数称为指针函数,其定义的一般形式如下:

<类型标识符>*函数名(形参表)

{

函数体

}


例如:

int*ip;

int*fFun1(int x)

{

...

return ip;

}

其中fFun1是函数名,前面的“*”表示fFun1是一个指针函数(注意与函数指针的区别),它的返回值是一个int类型的地址。与此相匹配的是,在函数体内return语句中的ip也必须是指向int型的指针变量。


C++函数的返回类型,可以是除数组和函数外的任何类型包括指针

【例】 指针作为函数的返回值的例子

先问用户要输入多少个实数,然后分配一存储空间保存输入的这些实数,并把指向这空间的指针返回给用户。

#include <iostream.h>

float *input(int& n);

void main( )

{ int num; float *P;

P = input(num);

if(P)

{ for(int i=0; i<num; i++)

cout<<P[i]<<" ";

delete P;

}

}

float *input(int& n)

{ int num;

cout<<“要输入多少个实数:”;

cin >> num;

if(num<=0) return NULL;

float *buf=new float[num];

if(buf==NULL) return;

n = num;

for(int i=0; i<num; i++)

cin>>buf[i];

return buf;

}

55


1、写一个函数,找出从键盘输入的字符串中大写字母字符(即’A’-‘Z’这26个字母)的个数(如字符串”China Computer Wrold”中大写字母字符的个数为3个)。

函数的原型:int CalcCapital (char *str);

函数参数: str为所要处理的字符串;

函数返回值: 所给字符串中数字字符的个数


int CalcCapital (char *str)

{ if (str == NULL) return 0; //判断字符指针是否为空

int num = 0; //记录大写字母字符个数的变量,初值为0

for(int i=0; str[i] != ‘\0’; i++)

if (str[i] <= 'A' && str[i] >= 'Z') num++;

//若是大写字母,则总数加1

return num; //返回大写字母字符数

}

#include<iostream.h>

void main( )

{char s[20];

cin.getline(s,20);

cout<< CalcCapital(s);}


2.下列各项中不符合函数重载必须满足的条件的是( )

A. 必须有不同的参数个数  

B.对应的参数类型必须不相同

C. A和B必须同时满足  

D.A和B只要满足一个即可

3.下列带缺省值参数的函数说明中,正确的说明是( )

A.int Fun(int x,int y=2,int z=3);

B.int Fun(int x=1,int y,int z=3);

C. int Fun(int x,int y=2,int z);

D.int Fun(int x=1,int y=3,int z);


4 为了提高程序的运行速度,可将不太复杂的功能用函数实现,此函数应选择。

A.内联函数 B.重载函数

C.递归函数 D.函数模板

5 . 函数原型语句正确的是。

A. int Function(void a); B.void Function (int);

C. int Function(a); D.void int(double a);

6. C++中函数返回值的类型是由决定的。

A. return语句中表达式的类型 B.该函数定义时的类型

C.调用函数时的调用语句 D.系统根据结果

7. 以下函数的返回结果是。

int function(char * x)

{

char *p = x; while (*p++); return (p-x-1);

}

A. 求字符串的长度 B.将字符串x连接到字符串p后面

C. 将字符串x复制到字符串p中 D.将字符串x反向存放


8.函数调用func((exp1,exp2),(exp3,exp4,exp5))中所含实参的个数为个。

A. 1 B. 2 C. 4 D. 5

9.以下正确的函数原型语句是。

A. double fun(int x , int y)

B. double fun(int x ; int y)

C. double fun(int , int);

D. double fun(int x , y);

10.面向对象方法的多态性是指。

A. 一个类可以派生出多个特殊类

B. 一个对象在不同的运行环境中可以有不同的变体

C. 针对一消息,不同的对象可以以适合自身的方式加以响应。

D. 一个对象可以是由多个其他对象组合而成的


11.所谓数据封装就是将一组数据和与这组数据有关操作组装在一起,形成一个实体,这实体也就是 ( )  A. 类 B. 对象 C. 函数体 D. 数据块 

12.在 ( ) 情况下适宜采用 inline 定义内联函数。  A. 函数体含有循环语句  B. 函数体含有递归语句  C. 函数代码少、频繁调用  D. 函数代码多、不常调用 

13 在 C++ 中,数据封装要解决的问题是 ( ) 。  A. 数据规范化排列 B. 数据高速转换  C. 避免数据丢失 D. 保证数据完整性 

14.所谓多态性是指 (      )A. 不同的对象调用不同名称的函数         

B. 不同的对象调用相同名称的函数C. 一个对象调用不同名称的函数          

D. 一个对象调用不同名称的对象


写出运行结果

# include <iostream.h>

const int N = 5;

void fun( );

void main( ) {

for (int i=1; i<N; i++)

fun( );

}

void fun( )

{

static int a;

int b=2;

cout <<(a += 3 , a+b)<<" ";

}


5 8 11 14


2.5 基本运算符和表达式

2.5.1 关系运算符

2.5.2 算术运算符

2.5.3 逻辑运算符

2.5.4 位运算符

2.5.5 条件运算符

2.5.6 逗号表达式

2.5.7sizeof运算符

2.6赋值及运算顺序

2.7 类型转换

30


2.8 语句

2.8.1 表达式语句、空语句和块语句

2.8.2 选择语句

1. if 语句

2. switch 语句

2.8.3 循环

1. while 语句

2. do while 语句

3. for 语句

2.8.4 转移

1. break 与 continue 语句

2. goto 语句

2.8.5 return 语句

31


2.9 函数

2.9.1 函数的基础知识 函数先声明再调用后定义的例子

#include <iostream.h>

void main( )

{ int a,b,c;

int sum(int, int); //先申明sum()函数

a=25; b=36;

c=sum(a,b); //调用sum()函数

cout << c << endl;

}

int sum(int x, int y) //定义sum()函数

{ int temp;

temp=x+y;

return temp;

}

32


a

m

56

56

t

b

n

78

78

l

r

s

a

56

b

78

r

  • int maxj(int a, int b)

  • { int r,t;

  • if(a<b) {t=a;a=b;b=t;}

  • r=a%b;

  • while(r!=0){

    • a=b; b=r;

    • r=a%b;

  • }

  • return b;

  • }

//习题 函数(7.1)

#include <stdio.h>

void main()

{

int m,n,l,s;

int maxj(int a, int b);

int minb(int a, int b);

printf("输入个正整数:");

scanf("%d,%d",&m,&n);

if (m>0 && n>0) {

l=maxj(m,n);

s=minb(m,n);

printf("%d和%d的最大公约数为%d\n",m,n,l);

printf("%d和%d的最小公倍数为%d\n",m,n,s);

}

else printf("输入了负数!\n");

return;

}

  • int minb(int a, int b)

  • { int r;

  • r=maxj(a,b);

  • if (r!=0)

  • return a*b/r;

  • else

    • return 0;

  • }

33


a[254]

a[0]

a[1]

a

a

b

c

d

e

f

\0

b

b[0]

b[1]

//习题 函数(7.5)

#include <iostream.h>

#include <stdio.h>

#include <string.h>

void main()

{ char a[255];

void convert(char b[]);

printf("请输入一个字符串: \n");

gets(a);

convert(a);

printf("该字符串反序为: \n");

puts(a);

return;

}

void convert(char b[])

{ int l,i;

char c;

l=strlen(b);

for(i=0; i<=l/2 ;i++){

c=b[i]; b[i]=b[l-i-1]; b[l-i-1]=c;}

return ;

}

c

34


m#include <stdio.h>

#include <math.h>

void main()

{ float a,b,c,d,x[2];

void root0(float a, float b, float c, float d,float x[]);

void root1(float a, float b, float c,float x[]);

void root2(float a, float b, float c, float d, float x[]);

printf("请输入一元二次方程的三个系数 a,b,c:\n");

scanf("%f,%f,%f",&a,&b,&c);

if(a<=1e-6) printf("不是一元二次方程!\n");

else {

printf("方程 (%4.1f)x*x+(%4.1f)x+(%4.1f)=0\n",a,b,c);

d=b*b-4*a*c;

if (d<0){

root0(a,b,c,d,x);

printf("由于b*b-4*a*c<0 因此有二个虚根:\n");

printf("x1 = %f + %f i\n",x[0],x[1]);

printf("x2 = %f - %f i\n", x[0],x[1]);

}

else if(d==0){

root1(a,b,c,x);

printf("由于b*b-4*a*c=0 因此有一个重根:\n");

printf("x1 = %f \n",x[0]);

printf("x2 = %f \n",x[1]);

}

x[0]

x[1]

35


else{

root2(a,b,c,d,x);

printf("由于b*b-4*a*c>0 因此有二个实根:\n");

printf("x1 = %f \n",x1);

printf("x2 = %f \n",x2);

}

}

return;

}

void root0(float a, float b, float c, float d,float x[])

{ x[0]=-b/(2*a); x[1]=sqrt(-d)/(2*a);

}

void root1(float a, float b, float c,float x[])

{ x[0]=x[1]==-b/(2*a);

}

void root2(float a, float b, float c, float d,float x[])

{ float r, i;

r=-b/(2*a); i=sqrt(d)/(2*a);

x[0]=r-i; x[1]=r+i;

}

36


2.9.2 参数传递及函数返回值

(1) 值传

一般变量

(2) 传地址

结构, 数组

(3) 传引用

一般变量, 结构, 数组

缺省参数

2.9.3 使用C++系统函数

37


2.10 数组

定义 类型 数组名[大小];

int a[4;];

int b[3][4];

int c[2][3][4];

使用时数组元素 数组名[表达式]

a[0]=10; i=3; a[i]=5;

b[0][3]=20;

初始值 定义时

int a[]={2,4,6,8,10};

int b[][3]={{2,4,6},{8,10,12}};

38


2.11 指针

定义 类型 *指针变量名;

2.11.1 使用指针

取地址运算符 &

取内容运算符 *

位移取值 [ ]

#include <iostream.h>

void main( )

{ int a[10]={2,4,6,8,10};

for(int *p=a;p<a+10;p++)

cout << p[+0] <<endl;

}

这里 p[+0] 位移+0 ,等价于 *p

p=a; p[+2] 即 *(p+2) p[-i] 即 *(p-i)

39


2.11.2 指针运算

1. 赋值

int x,*px,*q;

px=&x; q=px; 表示 q 和 px 同指一个地方(q跟着px指)

2. 比较

px= =q q!=px 判断 q 和 px 是否同指一个地方

p < q 判断 p 和 q 指在数组元素的前后

3. 移动指针

p=p+3; ++ -- 运算

y=*px++; //y=*(px++);

y=*++px; //y=*(++px);

y=++*px; //y=++(*px);

y=(*px)++;

40


2.11.3 指针和数组

1. 指向一维数组的指针 int a[4], *p;

p=a; 或 p=&a[0]; 即 p 指向 a[0];

2. 指针数组

许多个指针变量在一起都可用来指向整数

int *pa[2]; char *pc[5][7];

例#include <iostream.h>

void main( )

{ int a[2][3]={{2,4,6},{8,10,12}};

int *pa[2]; //有二个指针 pa[0] 和 pa[1]

pa[0]=a[0]; pa[1]=a[1];

for (int i=0; i<2; i++)

for(int j=0; j<3; j++,pa[i]++)

cout << "a["<<i<<"]["<<j<<"]=” <<*pa[i]<<endl;

}

41


3. 指向整个数组的指针(行指针)

如:int (*a)[5];

int b[2][5]={0,1,2,3,4,5,6,7,8,9}

a=b; a b 0 1 2 3 4

5 6 7 8 9

#include <iostream.h>

void main( )

{ int (*a)[5];

int b[2][5]={0,1,2,3,4,5,6,7,8,9};

a=b;

for(int i=0;i<5;i++)

cout << i <<":"<< *(*a+i)<<endl;

a++;

for(int i=0;i<5;i++)

cout << i <<":"<< *(*a+i)<<endl;

}

42


一维数组的地址

int a[4];

a+0 是第 0 列的地址 a+i 是第 i 列的地址

*( a+0) 是第 0 列的数据 *(a+i) 是第 i 列的数据

地址 a 数据 *a

&a[0] a[0]

一维数组的指针

int a[4], *p;

p=a;

可以p++

指针p 数据 *p

a[0]

43


二维数组的地址 *a a[0]

int a[3][4];*(a+i)+j是第 i 行第 j 列地址

*(*(a+i)+j)

a+0 是第 0行的地址

……….

a+i 是第 i 行的地址

*( a+0)是第 0行第 0 列的地址……..*(a+0)+j是第 0行第 j 列的地址

*(a+i)是第 i 行第 0 列的地址 ……... *(a+i)+j是第 i 行第 j 列的地址

*(*(a+0)+0)是第0行第0列的数据..(*(a+0)+j) 是第0行第j列的数据

*(*(a+i)+0)是第i行第0列的数据….*(*(a+i)+j) 是第i行第j列的数据

列地址 *(a+0)

行地址 a+0

行地址 a+i

44


二维数组的指针 *a a[0]

int a[3][4]; (p+i*4+j)是第i行第j列地址

(1) int *p;(小指针)

p=*a;∨

p=a; ㄨ

p=a[0]; ∨ *(p+i*4+j)

p=&a[0][0]; ∨

元素地址: p=*a+j;p+jp++;

元素数据: *p *(p+j) p[j]

*( a+0)是第 0行第 0 列的地址……..*(a+0)+j是第 0行第 j 列的地址

*(a+i)是第 i 行第 0 列的地址 ……... *(a+i)+j是第 i 行第 j 列的地址

*(*(a+0)+0)是第0行第0列的数据..(*(a+0)+j) 是第0行第j列的数据

*(*(a+i)+0)是第i行第0列的数据….*(*(a+i)+j) 是第i行第j列的数据

p 当一维数组名用但可 p=p+i p++ 走 (i)一行

元素地址: *p+j数据: *(*p+j) (*p)[j]

列地址 *(a+0)

45


num

score

next

结点

#include <stdlib.h>

申请空间函数:malloc(字节数)

测试字节运算符:sizeof(类型)

p=(struct student * )malloc(sizeof(struct student));

释放空间函数:free(指针);

free( p );

num

score

next

结点

p

struct student {

int num;

float score;

struct student *next

};

struct student *p;

46


p1=p2=(struct student * )malloc(LEN);

num

score

next

num

score

next

head

结点

p2

p1

p1

head

NULL

num

score

next

p2

p1

n= 0

20101

89.5

20103

90

NULL

scanf(“%d,%f”,&p1->num,&p1->score);

p1->num==0

head=p1;

p1=(struct student * )malloc(LEN);

scanf(“%d,%f”,&p1->num,&p1->score);

(n=2) p2->next=p1;

0

p2=p1;

2

1

47


head

01

03

07

08

11

NULL

p

p

p

head

01

03

07

08

11

NULL

p2

p1

p1

head

01

03

08

11

NULL

p1

p2

p1

05

p0

p2

48


2.11.4 引用

引用可为变量起别名,它主要用作函数参数以及函数的返回类型。有参数引用和返回值引用。

1. 引用说明

int num=50;

int& ref=num;

表示放整数 50 的内存空间 可叫 num,又可叫 ref

引用实质上是为另一个变量建立别名。

2. 引用参数(传引用)

49


3. 返回引用的函数

当一个函数的返回值需重新赋值的时候,我们也可对

返回值进行引用,这时函数可出现在赋值号的左边。

这种函数称为返回引用的函数。

形式 类型& 函数名(参数)

#include <iostream.h>

int a[]={2,4,6,8,10,12};

int& index(int i);

void main( )

{ index(3)=16; //index(3) 即返回值a[i],i=3,a[3]改为16

cout<<index(3)<<endl; cout <<a[3]<<endl;

}

int& index(int i)

{ return a[i]; }

注意: 返回值是函数内的局部变量时不能引用

50


#include <iostream.h>

int e(int i)

{ return i+1; }

int &f()

{ int i=1;

return ++i;

}

int g(int &i)

{ i=i+1;

return i;

}

main()

{

int r1=e(3);

int &r2=e(4);

int r3=f();

int &r4=f();

int a=0,b=0,c=0,d;

d=g(4);

a+=g(g(c));

b+=g(e(3));

return 1;

}

51


2.11.5 void类型指针

void指针是一个特殊指针,它可以指向任一类型的C++对象。

void main()

{ void *vp; int i=5; floatf=7.8; char c='A';

int *ip; float *fp; char *cp;

ip=&i; vp=&i;

cp=&c; vp=&c;

fp=&f; vp=&f;

vp=ip; vp=fp; vp=cp;

ip=vp; cp=vp; fp=vp; //错误

}

52


2.12 类型定义

typedef 类型名 标识符

2.13 指针和动态内存分配

C++的基本操作符 new 和 delete

分配内存: 指针变量名=new 类型[大小];

int *ip;

ip=new int[5];

释放内存

delete ip;

53


2.14 指针和函数

指针变量可以作函数的参数,指针也可作函数的返回值,还有一种指针可以用来指向函数

2.14.1 指针作为函数的参数

函数中的形参,可以是指针变量。这时实参可以是地址或指针来调用它

【例】 指针作为参数的例子

#include <iostream.h>

void main( )

{ int a[15];

void input(int *s, int n);

input(a,15);

for(int i=0; i<15; i++)

cout<<a[i]<<endl;

}

void input(int *s, int n)

{ cout<<“请输入”<<n<<“个整数:”<<endl;

for(int i=0; i<n; i++)

cin>>s[i]; //或 cin>>*s++;

}

54


2.14.2 返回指针的函数

C++函数的返回类型,可以是除数组和函数外的任何类型包括指针

【例】 指针作为函数的返回值的例子

先问用户要输入多少个实数,然后分配一存储空间保存输入的这些实数,并把指向这空间的指针返回给用户。

#include <iostream.h>

float *input(int& n);

void main( )

{ int num; float *data;

data = input(num);

if(data)

{ for(int i=0; i<num; i++)

cout<<data[i]<<" ";

delete data;

}

}

float *input(int& n)

{ int num;

cout<<“要输入多少个实数:”;

cin << num;

if(num<=0) return 0;

float *buf=new float[num];

if(buf==0) return;

n = num;

for(int i=0; i<num; i++)

cin>>buf[i];

return buf;

}

55


2.14.3 指向函数的指针变量

C++中函数也有地址,也可以用指针指向它。

这种指针的定义方法 : int (*funp)(int a, int b);

表示 funp 是指针,可以用来指向带有两个int类型参数的函数,这个函数的返回值是 int

函数 int fun(int a, int b)

{

..........…

}

funp=fun; funp 指向函数 fun

可以用这种指针调用函数

result=(*funp)(5,10); 或 result=fnup(5,10);

56


在C++中,字符串被定义为以 '\0'结束的字符数组。

char str[7]={'s','t','r','i','n','g','\0'};

char str[7]="string";

char *ps="string"; 或分成 char *ps; ps="string";

但数组不能分成 char str[7]; str="string"; //错误

串可以作为一个整体输入输出:

#include <iostream.h>

void main( )

{ char str[]="请输入一个字符串:";

char entstr[25];

cout << str;

cin >> entstr;

cout << "\n您输入的字符串是:" << entstr;

}

57


习题

2.1

2.3

2.7

2.8

2.9

58


  • Login