《第6章数组指针和字符串.ppt》由会员分享,可在线阅读,更多相关《第6章数组指针和字符串.ppt(39页珍藏版)》请在三一文库上搜索。
1、C+语言程序设计基础,第6章 数组、指针和字符串,6.1 数组 6.2 指针 6.3 动态内存分配 6.4 用vector创建数组对象 6.5 深复制和浅复制 6.6 字符串,6.1 数组,1、一维数组 ; int a3+2; char b3; const int SIZE=10;int mSIZE; 数组元素的表示: 为常量表达式;从0开始; 各个元素在内存中按其下标的升序顺序连续存放 数组元素的初始化 int a3=1,2,3,b4=6,7,c2;,多维数组, ; int a34; double b234; 数组元素的表示 各个元素在内存中连续存放 数组元素的初始化 int d23=1,2
2、,3,4,5,6; int d23=1,2,3,4,5,6; int a23=1,2,3;,思考,a00,a10,a20,a00,a01,a02,a03,a20,a21,a22,a23,a23,a00,练习:aij是二维数组中的第几个元素?,二维数组a34,6.1.3 数组作为函数参数,void fun(int b,int n) for(int i=0;in-1;i+) b7+=bi; int main() int a8=1,3,5,7,9,11,13, m=8; fun(a,m); couta7endl; return 0; ,数组练习,一维数组:编写函数,实现对给定数组中的元素逆序。 二维
3、数组:打印杨辉三角。,6.1.4 对象数组,对象数组 CDate date31; date0.SetDate(2012,10,1); date0.PrintDate(); 对象数组的初始化 CDate a2= CDate(2050,10,1), CDate(2050,10,2) ; CDate a2; a0= CDate(2050,10,1); a1= CDate(2050,10,2);,6.2 指针,6.2.1 内存空间的访问方式 声明变量,分配内存 指针是变量在内存中起始地址 变量的地址: 注:实际应用中更多的是通过&引用变量的指针,而很少关心指针的实际值,6.2.2 指针变量的声明, *
4、; 指针声明时指定的数据类型是指针所指向目标的数据类型 一个指针变量只能指向数据类型指定的同一类型的变量 *表示变量为指针变量 指针变量在使用前一定要先赋值后使用 char *pName; int *px;,6.2.4 指针的赋值, *=; int a=1,*p1= /给p2所指向的变量赋值,1,2,3,6.2.5 指针运算,一个指针可以加或减一个整数n double a10,*p=a; /p指向a0 p=p+3; /p指向a3 p-;,6.2.6 用指针处理数组元素,/统计输入字符串的字符个数 int main() char str20,*pc=str; coutpc; while(*pc!
5、=0) pc+; cout“The string Length:“pc-strendl; return 0; ,6.2.8 用指针作为函数参数,编写函数,将浮点数的整数部分和小数部分分离返回。,void splitFloat(float x, int *intPart, float *fracPart) *intPart = static_cast(x);/取x的整数部分 *fracPart = x - *intPart; /取x的小数部分 ,6.2.11 对象指针,1.对象指针的一般概念 *; CDate d, *pd; pd= (*pd).ypd-y (*pd).SetDate(2012,
6、8,8) pd-SetDate(2012,8,8),2.this指针,this是一个隐含于每一个类内非静态成员函数中的特殊指针 用于指向正在操作该成员函数的对象 this是指向自己的指针 *this就是自己,class M public: M( ) a=b=0; M(int i,int j) a=i;b=j; void copy(M ,3.指向类的非静态成员的指针,指向数据成员的指针: :* 指向成员函数的指针: (:*)(),class A public: A(int i) a=i; int fun(int b) return a*c+b; int c; private: int a; ;
7、int A:*pc= /指向类A的成员函数fun的指针pfun,6.3 动态内存分配,1、new运算符 申请一个变量的存储空间 =new ; double *px; px=new double; 申请一个带初始化的内存空间 =new (); float *py; py=new float(10.5f); 申请某个数据类型的一个匿名数组 =new ; int *pa; pa=new int5;,2、delete运算符,delete ; delete ; 说明: delete作用的指针对象必须由new分配的内存空间的首地址。 对于一个已分配内存的指针,只能用delete释放一次。,int main
8、() double *px; int *pz; px=new double; *px=66.84; cout*pxendl; pz=new int3; for(int i=0;i3;i+) pzi=i; coutpzi; delete px; delete pz; return 0; ,将动态数组封装成类,更加简洁,便于管理 建立和删除数组的过程比较繁琐 封装成类后更加简洁,便于管理 可以在访问数组元素前检查下标是否越界 用assert来检查,assert只在调试时生效,20,动态数组类,#include #include using namespace std; class Point pu
9、blic: Point() : x(0), y(0) int getX() const return x; int getY() const return y; void move(int newX, int newY) x = newX; y = newY; private: int x, y; ;,21,class ArrayOfPoints /动态数组类 public: ArrayOfPoints(int size) : size(size) /同名只能在初始化列表赋值 points = new Pointsize; ArrayOfPoints() delete points; Poin
10、t ,22,int main() int count; cout count; ArrayOfPoints points(count);/创建对象数组 points.element(0).move(5, 0); /通过访问数组元素的成员 points.element(1).move(15, 20); /通过类访问数组元素的成员return 0; ,23,6.4 用vector创建数组对象,为什么需要vector? 将动态数组封装,自动创建和删除 数组下标越界检查 vector动态数组对象的定义 vector 数组对象名(数组长度); 例:vector arr(5); 建立大小为5的int数组,
11、24,vector数组对象的使用,对数组元素的引用 与普通数组具有相同形式: 数组对象名 下标表达式 但vector数组对象名不表示数组首地址 获得数组长度 用size函数 数组对象名.size(),25,vector应用举例,#include #include using namespace std; /计算数组arr中元素的平均值 double average(const vector ,26,int main() unsigned n; cout n; vector arr(n); /创建数组对象 cout arri; cout “Average = “average(arr) endl
12、; return 0; ,27,6.5 深复制与浅复制,深复制:如果一个类的数据成员需要使用动态分配的堆资源,并且这个类的对象之间发生了数据成员拥有的堆资源复制过程,这个过程就可以叫深复制 浅复制:对象存在数据成员拥有堆资源但复制过程并未实现数据成员拥有堆资源的复制情况视为浅复制,#include #include class CPerson public: CPerson(char *str) cout“Construct“strendl; name=new charstrlen(str)+1; strcpy(name,str); CPerson() cout“Destruct“nameen
13、dl; delete name; private: char *name; ; void main() CPerson p1(“Randy“),p2(p1); ,编译正确; 运行时产生错误,浅复制,class CPerson public: CPerson(char *str) cout“Construct“strendl; name=new charstrlen(str)+1; strcpy(name,str); CPerson(CPerson ,深复制,6.6.1 用字符数组存储和处理字符串,字符串常量(例:“program“) 各字符连续、顺序存放,每个字符占一个字节,以0结尾,相当于一
14、个隐含创建的字符常量数组 “program”出现在表达式中,表示这一char数组的首地址 首地址可以赋给char常量指针: const char *STRING1 = “program“; 字符串变量 可以显式创建字符数组来表示字符串变量,例如,以下三条语句具有等价的作用: char str8 = p, r, o, g, r, a, m, 0 ; char str8 = “program“; char str = “program“;,31,字符数组练习,编写一函数,用于删除字符串中的给定字符。函数原型为: int delete(char s,char c); 如:若s字符串为”abcaabc
15、abcda”,要删除的字符为a,则删除后的字符串为”bcbcbcd”。,用字符数组表示字符串的缺点,用字符数组表示字符串的缺点 执行连接、拷贝、比较等操作,都需要显式调用库函数,很麻烦 当字符串长度很不确定时,需要用new动态创建字符数组,最后要用delete释放,很繁琐 字符串实际长度大于为它分配的空间时,会产生数组下标越界的错误 解决方法 使用字符串类string表示字符串 string实际上是对字符数组操作的封装,33,6.6.2 string类,常用构造函数 string(); /缺省构造函数,建立一个长度为0的串 string(const char *s); /用指针s所指向的字符串
16、常量初始化string类的对象 string(const string /执行拷贝构造函数,用s2的值作为s3的初值,34,string的用法,常用操作符 s + t 将串s和t连接成一个新串 s = t 用t更新s s = t 判断s与t是否相等 s != t 判断s与t是否不等 s t 判断s是否大于t (按字典顺序比较) s = t 判断s是否大于或等于t (按字典顺序比较) si 访问串中下标为i的字符 例: string s1 = “abc”, s2 = “def”; string s3 = s1 + s2; /结果是”abcdef” bool s4 = (s1 s2); /结果是t
17、rue char s5 = s21; /结果是e,35,36,例6.23 string类应用举例,#include #include using namespace std; /根据value的值输出true或false,title为提示文字 inline void test(const char *title, bool value) cout title “ returns “ (value ? “true“ : “false“) endl; ,int main() string s1 = “DEF“; cout s2; cout “length of s2: “ s2.length()
18、endl; /比较运算符的测试 test(“s1 = “ABC“, s1 = “ABC“); test(“DEF“ = s1“, “DEF“ = s1); /连接运算符的测试 s2 += s1; cout “s2 = s2 + s1: “ s2 endl; cout “length of s2: “ s2.length() endl; return 0; ,37,用getline输入整行字符串,输入整行字符串 用cin的操作符输入字符串,会以空格作为分隔符,空格后的内容会在下一回输入时被读取 用string头文件中的getline可以输入整行字符串,例如: getline(cin, s2);
19、以其它字符作为分隔符输入字符串 输入字符串时,可以使用其它分隔符作为字符串结束的标志(例如逗号、分号) 把分隔符作为getline的第3个参数即可,例如: getline(cin, s2, ,);,38,例6.24 用getline输入字符串,39,include #include using namespace std; int main() for (int i = 0; i 2; i+) string city, state; getline(cin, city, ,); getline(cin, state); cout “City:“ city “ State:“ state endl; return 0; ,Beijing,China City: Beijing State: China San Francisco,the United States City: San Francisco State: the United States,
链接地址:https://www.31doc.com/p-2567094.html