C++语言程序设计:第5、6、7、8章.ppt_第1页
C++语言程序设计:第5、6、7、8章.ppt_第2页
C++语言程序设计:第5、6、7、8章.ppt_第3页
C++语言程序设计:第5、6、7、8章.ppt_第4页
C++语言程序设计:第5、6、7、8章.ppt_第5页
已阅读5页,还剩277页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,第五章 c+程序的结构,清华大学 郑 莉,c+语言程序设计,2,本章主要内容,作用域与可见性 对象的生存期 数据与函数 静态成员 共享数据的保护 友元 编译预处理命令 多文件结构和工程,3,函数原型的作用域,函数原型中的参数,其作用域始于 “(“,结束于“)“。 例如,设有下列原型声明: double area(double radius);,radius 的作用域仅在于此,不能用于程序正文其它地方,因而可有可无。,作用域与可见性,4,块作用域,在块中声明的标识符,其作用域自声明处起,限于块中,例如: void fun(int a) int b(a); cinb; if (b0) int c; ,作用域与可见性,5,类作用域,类作用域作用于特定的成员名。 类x的成员m具有类作用域,对m的访问方式如下: 如果在x的成员函数中没有声明同名的局部作用域标识符,那么在该函数内可以访问成员m。 通过表达式x.m或者x:m访问。 通过表达式prt-m,作用域与可见性,6,文件作用域,不在前述各个作用域中出现的声明,具有文件作用域,这样声明的标识符的作用域开始于声明点,结束于文件尾。,作用域与可见性,7,可见性,可见性是从对标识符的引用的角度来谈的概念 可见性表示从内层作用域向外层作用域“看”时能看见什么。 如果标识在某处可见,则就可以在该处引用此标识符。,作用域与可见性,8,可见性,标识符应声明在先,引用在后。 如果某个标识符在外层中声明,且在内层中没有同一标识符的声明,则该标识符在内层可见。 对于两个嵌套的作用域,如果在内层作用域内声明了与外层作用域中同名的标识符,则外层作用域的标识符在内层不可见。,作用域与可见性,9,同一作用域中的同名标识符,在同一作用域内的对象名、函数名、枚举常量名会隐藏同名的类名或枚举类型名。 重载的函数可以有相同的函数名。,作用域与可见性,10,#include using namespace std; int i; /文件作用域 int main() i=5; int i; /块作用域 i=7; cout“i=“iendl; /输出7 cout“i=“i; /输出5 return 0; ,作用域与可见性,例 5.1,11,对象的生存期,对象从产生到结束的这段时间就是它的生存期。在对象生存期内,对象将保持它的值,直到被更新为止。,12,静态生存期,这种生存期与程序的运行期相同。 在文件作用域中声明的对象具有这种生存期。 在函数内部声明静态生存期对象,要冠以关键字static 。,对象的生存期,13,#include using namespace std; int i=5; /文件作用域 int main() cout“i=“iendl; return 0; i具有静态生存期,对象的生存期,例,14,动态生存期,块作用域中声明的,没有用static修是的对象是动态生存期的对象(习惯称局部生存期对象)。 开始于程序执行到声明点时,结束于命名该标识符的作用域结束处。,对象的生存期,15,#include using namespace std; void fun(); int main() fun(); fun(); void fun() static int a=1; int i=5; a+; i+; cout“i=“i“,a=“aendl; ,运行结果: i=6, a=2 i=6, a=3 i是动态生存期 a是静态生存期,对象的生存期,例,16,例5-2 变量的生存期与可见性,#include using namespace std; int i=1; / i 为全局变量,具有静态生存期。 int main() static int a; / 静态局部变量,有全局寿命,局部可见。 int b=-10; / b, c为局部变量,具有动态生存期。 int c=0; void other(void); cout“-main-n“; cout“ i: “i“ a: “a“ b: “b“ c: “cendl; c=c+8; other(); cout“-main-n“; cout“ i: “i“ a: “a“ b: “b“ c: “cendl; i=i+10; other(); ,对象的生存期,void other(void) static int a=2; static int b; / a,b为静态局部变量,具有全局寿命,局部可见。 /只第一次进入函数时被初始化。 int c=10; / c为局部变量,具有动态生存期, /每次进入函数时都初始化。 a=a+2; i=i+32; c=c+5; cout“-other-n“; cout“ i: “i“ a: “a“ b: “b“ c: “cendl; b=a; ,17,运行结果: -main- i: 1 a: 0 b: -10 c: 0 -other- i: 33 a: 4 b: 0 c: 15 -main- i: 33 a: 0 b: -10 c: 8 -other- i: 75 a: 6 b: 4 c: 15,18,19,例5-3具有静态、动态生存期对象的时钟程序,#include using namespace std; class clock /时钟类声明 public: /外部接口 clock(); void settime(int newh, int newm, int news); /三个形参均具有函数原型作用域 void showtime(); clock() private: /私有数据成员 int hour,minute,second; ;,对象的生存期,/时钟类成员函数实现 clock:clock() /构造函数 hour=0; minute=0; second=0; void clock:settime(int newh, int newm, int news) hour=newh; minute=newm; second=news; void clock:showtime() couthour“:“minute“:“secondendl; ,20,clock globclock; /声明对象globclock, /具有静态生存期,文件作用域 int main() /主函数 cout“first time output:“endl; /引用具有文件作用域的对象: globclock.showtime(); /对象的成员函数具有类作用域 globclock.settime(8,30,30); clock myclock(globclock); /声明具有块作用域的对象myclock cout“second time output:“endl; myclock.showtime(); /引用具有块作用域的对象 ,21,程序的运行结果为: first time output: 0:0:0 second time output: 8:30:30,22,23,数据与函数,数据存储在局部对象中,通过参数传递实现共享函数间的参数传递。 数据存储在全局对象中。 将数据和使用数据的函数封装在类中。,数据与函数,24,使用全局对象,#include using namespace std; int global; void f() global=5; void g() coutglobalendl; int main() f(); g(); /输出“5” return 0; ,数据与函数,25,将函数与数据封装,#include using namespace std; class application public: void f(); void g(); private: int global; ; void application:f() global=5; void application:g() coutglobalendl;,int main() application myapp; myapp.f(); myapp.g(); return 0; ,数据与函数,26,静态成员,静态数据成员 用关键字static声明 该类的所有对象维护该成员的同一个拷贝 必须在类外定义和初始化,用(:)来指明所属的类。 静态成员函数 类外代码可以使用类名和作用域操作符来调用静态成员函数。 静态成员函数只能引用属于该类的静态数据成员或静态成员函数。,静态成员,27,例5-4 具有静态数据成员的 point类,#include using namespace std; class point public: point(int xx=0, int yy=0) x=xx; y=yy; countp+; point(point ,静态成员,point:point(point ,28,29,静态成员函数举例,#include using namespace std; class application public: static void f(); static void g(); private: static int global; ; int application:global =0;,void application:f() global=5; void application:g() coutglobalendl; int main() application:f(); application:g(); return 0; ,静态成员,30,静态成员函数举例,class a public: static void f(a a); private: int x; ; void a:f(a a) coutx; /对x的引用是错误的 couta.x; /正确 ,静态成员,31,具有静态数据、函数成员的 point类,#include using namespace std; class point /point类声明 public: /外部接口 point(int xx=0, int yy=0) x=xx;y=yy;countp+; point(point ,静态成员,point:point(point /输出对象号,类名引用 ,32,33,友元,友元是c+提供的一种破坏数据封装和数据隐藏的机制。 通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息。 可以使用友元函数和友元类。 为了确保数据的完整性,及数据封装与隐藏的原则,建议尽量不使用或少使用友元。,友 元,34,友元函数,友元函数是在类声明中由关键字friend修饰说明的非成员函数,在它的函数体中能够通过对象名访问 private 和 protected成员 作用:增加灵活性,使程序员可以在封装和快速性方面做合理选择。 访问对象中的成员必须通过对象名。,友 元,35,例5-6 使用友元函数计算两点距离,#include #include using namespace std; class point /point类声明 public: /外部接口 point(int xx=0, int yy=0) x=xx;y=yy; int getx() return x; int gety() return y; friend float distance(point ,友 元,double distance( point ,36,37,友元类,若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员。 声明语法:将友元类名在另一个类中使用friend修饰说明。,友 元,38,友元类举例,class a friend class b; public: void display() coutxendl; private: int x; class b public: void set(int i); void display(); private: a a; ;,友 元,void b:set(int i) a.x=i; void b:display() a.display(); ,39,40,友元关系是单向的,如果声明b类是a类的友元,b类的成员函数就可以访问a类的私有和保护数据,但a类的成员函数却不能访问b类的私有、保护数据。,41,常类型,常类型的对象必须进行初始化,而且不能被更新。 常引用:被引用的对象不能被更新。 const 类型说明符 &引用名 常对象:必须进行初始化,不能被更新。 类名 const 对象名 常数组:数组元素不能被更新(下一章介绍)。 类型说明符 const 数组名大小. 常指针:指向常量的指针(下一章介绍)。,共享数据的保护,42,例5-7常引用做形参,#include using namespace std; void display(const double ,共享数据的保护,43,常对象举例,class a public: a(int i,int j) x=i; y=j; . private: int x,y; ; a const a(3,4); /a是常对象,不能被更新,共享数据的保护,44,用const修饰的对象成员,常成员函数 使用const关键字说明的函数。 常成员函数不更新对象的数据成员。 常成员函数说明格式: 类型说明符 函数名(参数表)const; 这里,const是函数类型的一个组成部分,因此在实现部分也要带const关键字。 const关键字可以被用于参与对重载函数的区分 通过常对象只能调用它的常成员函数。 常数据成员 使用const说明的数据成员。,共享数据的保护,45,例5-8 常成员函数举例,#include using namespace std; class r public: r(int r1, int r2)r1=r1;r2=r2; void print(); void print() const; private: int r1,r2; ;,共享数据的保护,void r:print() coutr1“:“r2endl; void r:print() const coutr1“;“r2endl; int main() r a(5,4); a.print(); /调用void print() const r b(20,52); b.print(); /调用void print() const ,46,47,例5-9 常数据成员举例,#include using namespace std; class a public: a(int i); void print(); const int,共享数据的保护,const int a:b=10; a:a(int i):a(i),r(a) void a:print() couta“:“b“:“rendl; int main() /*建立对象a和b,并以100和0作为初值,分别调用构造函数,通过构造函数的初始化列表给对象的常数据成员赋初值*/ a a1(100),a2(0); a1.print(); a2.print(); ,48,49,编译预处理命令,#include 包含指令 将一个源文件嵌入到当前源文件中该点处。 #include 按标准方式搜索,文件位于c+系统目录的include子目录下 #include“文件名“ 首先在当前目录中搜索,若没有,再按标准方式搜索。 #define 宏定义指令 定义符号常量,很多情况下已被const定义语句取代。 定义带参数宏,已被内联函数取代。 #undef 删除由#define定义的宏,使之不再起作用。,50,条件编译指令 #if 和 #endif,#if 常量表达式 /当“ 常量表达式”非零时编译 程序正文 #endif ,编译预处理命令,51,条件编译指令#else,#if 常量表达式 /当“ 常量表达式”非零时编译 程序正文1 #else /当“ 常量表达式”为零时编译 程序正文2 #endif,编译预处理命令,52,条件编译指令 #elif,#if 常量表达式1 程序正文1 /当“ 常量表达式1”非零时编译 #elif 常量表达式2 程序正文2 /当“ 常量表达式2”非零时编译 #else 程序正文3 /其它情况下编译 #endif,编译预处理命令,53,条件编译指令,#ifdef 标识符 程序段1 #else 程序段2 #endif 如果“标识符”经#defined定义过,且未经undef删除,则编译程序段1,否则编译程序段2。,编译预处理命令,54,条件编译指令,#ifndef 标识符 程序段1 #else 程序段2 #endif 如果“标识符”未被定义过,则编译程序段1,否则编译程序段2。,编译预处理命令,55,多文件结构(例5-10),一个源程序可以划分为多个源文件: 类声明文件(.h文件) 类实现文件(.cpp文件) 类的使用文件(main()所在的.cpp文件) 利用工程来组合各个文件。,56,不使用条件编译的头文件,/main.cpp #include “file1.h“ #include “file2.h“ int main() /file1.h #include “head.h“ ,/file2.h #include “head.h“ /head.h class point ,多文件结构,57,使用条件编译的头文件,/head.h #ifndef head_h #define head_h class point #endif,多文件结构,58,第六章 数组 指针与字符串,清华大学 郑 莉,c+语言程序设计,59,本章主要内容,数组 指针 动态存储分配 指针与数组 指针与函数 字符串,60,数组的概念,数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。 数组属于构造类型。,数 组,61,一维数组的声明与引用,一维数组的声明 类型说明符 数组名 常量表达式 ; 例如: int a10; 表示 a 为整型数组,有10个元素:a0.a9,引用 必须先声明,后使用。 只能逐个引用数组元素,而不能一次引用整个数组 例如:a0=a5+a7-a2*3,数 组,62,例6. 1一维数组的声明与引用,#include using namespace std; int main() int a10,b10; int i; for(i=0;i10;i+) ai=i*2-1; b10-i-1=ai; ,数 组,for(i=0;i10;i+) cout“a“i “=“ai; cout“ b“i “=“ biendl; ,63,一维数组的存储顺序,数组元素在内存中顺次存放,它们的地址是连续的。 例如:具有10个元素的数组 a,在内存中的存放次序如下:,数组名字是数组首元素的内存地址。 数组名是一个常量,不能被赋值。,数 组,64,一维数组的初始化,可以在编译阶段使数组得到初值: 在声明数组时对数组元素赋以初值。 例如:static int a10=0,1,2,3,4,5,6,7,8,9; 可以只给一部分元素赋初值。 例如:static int a10=0,1,2,3,4; 在对全部数组元素赋初值时,可以不指定数组长度。 例如:static int a=1,2,3,4,5,数 组,65,#include using namespace std; int main() int i; static int f20=1,1; /初始化第0、1个数 for(i=2;i20;i+) fi=fi-2+fi-1; /求第219个数 for(i=0;i20;i+) /输出,每行5个数/ if(i%5=0) coutendl; cout.width(12); /设置输出宽度为12 coutfi; ,例:用数组来处理求fibonacci数列问题,66,例:用数组来处理求fibonacci数列问题,运行结果: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765,67,一维数组应用举例,循环从键盘读入若干组选择题答案,计算并输出每组答案的正确率,直到输入ctrl+z为止。 每组连续输入5个答案,每个答案可以是ad。,数 组,68,#include using namespace std; int main() char key = a,c,b,a,d; char c; int ques = 0, numques = 5, numcorrect = 0; cout “enter the “ numques “ question tests:“ endl; while (cin.get(c) if (c != n) if (c = keyques) numcorrect+; cout “ “; else cout “*“; else cout “ score “float(numcorrect)/numques*100 “%“; ques = 0; / reset variables numcorrect = 0; cout endl; continue; ques+; ,68,69,运行结果: acbba * score 60% acbad score 100% abbda * * score 40% bdcba * score 0%,69,70,二维数组的声明及引用,数据类型 标识符常量表达式1常量表达式2 ; 例: int a53; 表示a为整型二维数组,其中第一维有5个下标(04),第二维有3个下标(02),数组的元素个数为15,可以用于存放5行3列的整型数据表格。,数 组,存储顺序 按行存放,上例中数组a的存储顺序为:,二维数组的声明 类型说明符 数组名常量表达式常量表达式 例如:float a34;,引用 例如:b12=a23/2,下标不要越界,二维数组的声明及引用,数 组,71,将所有数据写在一个内,按顺序赋值 例如:static int a34=1,2,3,4,5,6,7,8,9,10,11,12; 分行给二维数组赋初值 例如:static int a34=1,2,3,4,5,6,7,8,9,10,11,12; 可以对部分元素赋初值 例如:static int a34=1,0,6,0,0,11;,二维数组的初始化,数 组,72,73,数组作为函数参数,数组元素作实参,与单个变量一样。 数组名作参数,形、实参数都应是数组名,类型要一样,传送的是数组首地址。对形参数组的改变会直接影响到实参数组。,数 组,74,例6-2 使用数组名作为函数参数,主函数中初始化一个矩阵并将每个元素都输出,然后调用子函数,分别计算每一行的元素之和,将和直接存放在每行的第一个元素中,返回主函数之后输出各行元素的和。,数 组,75,#include using namespace std; void rowsum(int a4, int nrow) int sum; for (int i = 0; i nrow; i+) sum = 0; for(int j = 0; j 4; j+) sum += aij; cout “sum of row “ i “ is “ sum endl; ai0=sum; ,75,76,int main() int table34 = 1,2,3,4,2,3,4,5,3,4,5,6; for (int i = 0; i 3; i+) for (int j = 0; j 4; j+) cout tableij “ “; cout endl; rowsum(table,3); for (int i = 0; i 3; i+) cout tablei0 ,76,77,运行结果: 1 2 3 4 2 3 4 5 3 4 5 6 sum of row 0 is 10 sum of row 1 is 14 sum of row 2 is 18 10 14 18,77,78,对象数组,声明: 类名 数组名元素个数; 访问方法: 通过下标访问 数组名下标.成员名,数 组,79,对象数组初始化,数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象。 通过初始化列表赋值。 例: point a2=point(1,2),point(3,4); 如果没有为数组元素指定显式初始值,数组元素便使用默认值初始化(调用默认构造函数)。,数 组,80,数组元素所属类的构造函数,不声明构造函数,则采用默认构造函数。 各元素对象的初值要求为相同的值时,可以声明具有默认形参值的构造函数。 各元素对象的初值要求为不同的值时,需要声明带形参的构造函数。 当数组中每一个对象被删除时,系统都要调用一次析构函数。,数 组,81,例6-3 对象数组应用举例,/point.h #if !defined(_point_h) #define _point_h class point public: point(); point(int xx,int yy); point(); void move(int x,int y); int getx() return x; int gety() return y; private: int x,y; ; #endif,数 组,82,/6-2.cpp #include using namespace std; #include “point.h“ point:point() x=y=0; cout“default constructor called.“endl; point:point(int xx,int yy) x=xx; y=yy; cout “constructor called.“endl; point :point() cout“destructor called.“endl; void point :move(int x,int y) x=x; y=y; ,82,83,#include #include “point.h“ using namespace std; int main() cout“entering main.“endl; point a2; for(int i=0;i2;i+) ai.move(i+10,i+20); cout“exiting main.“endl; return 0; ,83,84,运行结果: entering main. default constructor called. default constructor called. exiting main. destructor called. destructor called.,84,85,关于内存地址,内存空间的访问方式 通过变量名访问 通过地址访问 地址运算符: 则&var 表示变量var在内存中的起始地址,86,声明 例:static int i; static int *i_pointer= 指向整型变量的指针,指针变量的概念,概念 指针:内存地址,用于 间接访问内存单元 指针变量: 用于存放地址的变量,引用 例1: i=3; 例2: *i_pointer=3;,指 针,87,指针变量的初始化,语法形式 存储类型 数据类型 *指针名初始地址; 例: int *pa= 注意事项 用变量地址作为初值时,该变量必须在指针初始化之前已说明过,且变量类型应与指针类型一致。 可以用一个已赋初值的指针去初始化另一 个指针变量。 不要用一个内部 auto 变量去初始化 static 指针。,指 针,88,指针变量的赋值运算,指针名=地址 “地址”中存放的数据类型与指针类型必须相符。 向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。 指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何一个指针本身的数据值都是unsigned long int型。 允许声明指向 void 类型的指针。该指针可以被赋予任何类型对象的地址。 例: void *general;,指 针,89,例6-5 指针的声明、赋值与使用,#include using namespace std; int main() int *i_pointer; /声明int型指针i_pointer int i; /声明int型数i i_pointer= /输出int型指针所指地址的内容 ,指 针,90,程序运行的结果是: output int i=10 output int pointer i=10,90,91,例6-6 void类型指针的使用,void vobject; /错,不能声明void类型的变量 void *pv; /对,可以声明void类型的指针 int *pint; int i; int main() pv = ,指 针,92,指向常量的指针,不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。 例1 char *name1 = “john“; /name1是一般指针 *name1=a; /编译正确,运行出错 例2 const char *name1 = “john“; /指向常量的指针 char s=“abc“; name1=s; /正确,name1本身的值可以改变 *name1=1; /编译时指出错误,指 针,93,指针类型的常量,若声明指针常量,则指针本身的值不能被改变。例: char *const name2 = “john“; name2=“abc“; /错误,指针常量值不能改变,94,指针变量的算术运算,指针与整数的加减运算 指针 p 加上或减去 n ,其意义是指针当前指向位置的前方或后方第 n 个数据的地址。 这种运算的结果值取决于指针指向的数据类型。 指针加一,减一运算 指向下一个或前一个数据。 例如:y=*px+ 相当于 y=*(px+) (*和+优先级相同,自右向左运算),指 针,95,pa,95,96,pb-1,pb,pb+1,pb+2,*(pb-1),*pb,*(pb+1),*(pb+2),long *pb,96,97,关系运算 指向相同类型数据的指针之间可以进行各种关系运算。 指向不同数据类型的指针,以及指针与一般整数变量之间的关系运算是无意义的。 指针可以和零之间进行等于或不等于的关系运算。例如:p=0或p!=0 赋值运算 向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。,指针变量的关系运算,指 针,98,指向数组元素的指针,声明与赋值 例: int a10, *pa; pa= 通过指针引用数组元素 经过上述声明及赋值后: *pa就是a0,*(pa+1)就是a1,. ,*(pa+i)就是ai. ai, *(pa+i), *(a+i), pai都是等效的。 不能写 a+,因为a是数组首地址是常量。,指 针,99,例6-7,设有一个int型数组a,有10个元素。用三种方法输出各元素: 使用数组名和下标 使用数组名和指针运算 使用指针变量,指 针,100,int main() int a10; int i; for(i=0; iai; coutendl; for(i=0; i10; i+) coutai; ,使用数组名和下标,100,101,int main() int a10; int i; for(i=0; iai; coutendl; for(i=0; i10; i+) cout*(a+i); ,使用数组名指针运算,102,使用指针变量,int main() int a10; int *p,i; for(i=0; iai; coutendl; for(p=a; p(a+10); p+) cout*p; ,103,指针数组,数组的元素是指针型 例:point *pa2; 由pa0,pa1两个指针组成,指 针,104,例6-8 利用指针数组存放单位矩阵,#include using namespace std; int main() int line1=1,0,0; /声明数组,矩阵的第一行 int line2=0,1,0; /声明数组,矩阵的第二行 int line3=0,0,1; /声明数组,矩阵的第三行 int *p_line3; /声明整型指针数组 p_line0=line1; /初始化指针数组元素 p_line1=line2; p_line2=line3;,指 针,105,/输出单位矩阵 cout“matrix test:“endl; for(int i=0;i3;i+) /对指针数组元素循环 for(int j=0;j3;j+) /对矩阵每一行循环 coutp_lineij“ “; coutendl; ,输出结果为: matrix test: 1,0,0 0,1,0 0,0,1,105,106,例6-9 二维数组举例,#include using namespace std; int main() int array223=11,12,13,21,22,23; for(int i=0;i2;i+) cout*(array2+i)endl; for(int j=0;j3;j+) cout*(*(array2+i)+j)“ “; /或者 coutarray2ij“ “; coutendl; ,指 针,107,在某次运行之后,程序的输出结果为: 0x0065fde0 11,12,13 0x0065fdec 21,22,23,107,108,以指针作为函数参数,以地址方式传递数据,可以用来返回函数处理结果。 实参是数组名时形参可以是指针。,指针与函数,109,例6.10,题目:读入三个浮点数,将整数部分和小数部分分别输出 #include using namespace std; void splitfloat(float x, int *intpart, float *fracpart) /形参intpart、 fracpart是指针 *intpart = int(x); / 取x的整数部分 *fracpart = x - *intpart; /取x的小数部分 ,指针与函数,110,int main() int i, n; float x, f; cout x; splitfloat(x, ,110,111,运行结果: enter three (3) floating point numbers 4.7 integer part is 4 fraction part is 0.7 8.913 integer part is 8 fraction part is 0.913 -4.7518 integer part is -4 fraction part is -0.7518,111,112,例: 输出数组元素的内容和地址,#include #include using namespace std; void array_ptr(long *p, int n) int i; cout “in func, address of array is “ unsigned long(p) endl; cout “accessing array in the function using pointers“ endl; for (i = 0; i n; i+) cout “ address for index “ i “ is “ unsigned long(p+i); cout “ value is “ *(p+i) endl; ,指针与函数,113,int main() long list5 = 50, 60, 70, 80, 90; cout “in main, address of array is “ unsigned long(list) endl; cout endl; array_ptr(list,5); ,114,运行结果: in main, address of array is 6684132 in func, address of array is 6684132 accessing array in the function using pointers address for index 0 is 6684132 value is 50 address for index 1 is 6684136 value is 60 address for index 2 is 6684140 value is 70 address for index 3 is 6684144 value is 80 address for index 4 is 6684148 value is 90,114,115,指向常量的指针做形参,#include using namespace std; const int n=6; void print(const int *p,int n); int main() int arrayn; for(int i=0;iarrayi; print(array,n); ,指 针,116,void print(const int *p, int n) cout“*p; for(int i=1;in;i+) cout“.“*(p+i); cout“endl; ,116,117,指针型函数,当函数的返回值是地址时,该函数就是指针形函数。 声明形式 存储类型 数据类型 *函数名(),指针与函数,118,声明形式 存储类型 数据类型 (*函数指针名)(); 含义: 数据指针指向数据存储区,而函数指针指向的是程序代码存储区。,指向函数的指针,指针与函数,119,例6-11函数指针,#include using namespace std; void print_stuff(float data_to_ignore); void print_message(float list_this_data); void print_float(float data_to_print); void (*function_pointer)(float); int main() float pi = (float)3.14159; float two_pi = (float)2.0 * pi;,指针与函数,120,print_stuff(pi); function_pointer = print_stuff; function_pointer(pi); function_pointer = print_message; function_pointer(two_pi); function_pointer(13.0); function_pointer = print_float; function_pointer(pi); print_float(pi); ,120,121,void print_stuff(float data_to_ignore) cout“this is the print stuff function.n“; void print_message(float list_this_data) cout“the data to be listed is “ list_this_dataendl; void print_float(float data_to_print) cout“the data to be printed is “ data_to_printendl; ,121,122,运行结果: this is the print stuff function. this is the print stuff function. the data to be listed is 6.283180 the data to be listed is 13.000000 the data to be printed is 3.141590 the data to be printed is 3.141590,122,123,对象指针的一般概念,声明形式 类名 *对象指针名; 例 point a(5,10); piont *ptr; ptr=,指 针,124,对象指针应用举例,int main() point a(5,10); point *ptr; ptr= ,指 针,125,曾经出现过的错误例子,class fred; /前向引用声明 class barney fred x; /错误:类fred的声明尚不完善 ; class fred barney y; ;,指 针,126,正确的程

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论