C++程序设计PPT电子课件教案-第六章 指针.ppt_第1页
C++程序设计PPT电子课件教案-第六章 指针.ppt_第2页
已阅读5页,还剩177页未读 继续免费阅读

下载本文档

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

文档简介

第六章 指针,c+程序设计,吕韫 2011-3,掌握指针变量的定义格式及引用方法 掌握指针变量的简单运算 掌握用new和delete运算符动态分配和回收内存空间的方法 掌握用指针变量处理一维数组和字符串数组的问题 掌握用指针变量、数组作为函数参数时函数的使用方法 了解指向函数的指针和指向指针的指针的使用方法,教学目标,教学内容,6.1 地址和指针,6.2 变量的指针和指向变量的指针变量,6.3 指针与数组,6.7 实例分析,6.8 本章小结,6.4 指针与字符串,6.5 指向函数的指针,6.6 指针数组和指向指针的指针,6.0 序:指针的优势,序:指针的优势,有效的表示复杂的数据结构 能动态的分配内存 更为方便的使用字符串 有效而方便的使用数组 调用函数时能得到多个返回值 能直接处理内存地址,6.0 序:指针的优势,地址和指针,6.1.1 变量的存储,6.1 地址和指针,内存单元与地址,内存单元是以字节为单位,每个字节都有一个编号(即“地址”)。如果将内存比作一个旅馆,内存单元就好比“房间号”,而实体则好比“旅客”。这些“旅客”(实体)中,有单人型(char),还有团体型(数组等)。每个“实体”占用的内存单元是不同的。如: char a;int b;float c;int d3;int max( ),1地址(address) 如果在程序中定义了一个“实体”(变量、数组、函数 ),编译时系统就要给这些实体分配内存单元。 分配规则:,计算机的内存储器被分割成许多相同的连续存储单元,相应每个存储单元都有一个唯一的编号,称之为地址。 假设程序里定义了3个变量i,j,k,编译时系统分配了2000和2001两个字节给变量i, 2002和2003给变量j, 2004和2005给变量k,如右图所示。在表内,变量的标识符与存储地址一一对应,运行程序时,对变量值的存取都是通过地址进行的。,内存单元与地址,内存单元与地址,2.变量的存储: 根据变量定义的数据类型,在内存中分配单元,main() char a; int b; float c; int d3; int max( ); ,通常我们关心的不是各个内存单元的具体地址值,而是每个实体的“起始地址”。,地址,变量的读取方式,方式: 直接访问:按变量的地址进行存取 间接访问:将变量的地址存放在另一个变量中的方式 图示: 直接访问:,间接访问:,地址,变量,值,指针变量,指针,返 回,6.1.2 变量的读取方式,实体地址的表示: 实体地址表示法1:直接访问(实体名) 普通变量a,b,c &a,&b,&c 数组d3 d(数组名), &d0,&d1,&d2 对二维数组,可用单下标法表示每行首地址。 如 对char x34,可用x0、x1、x2分别表示其第 一、二、三行的首地址。 函数max( ) max(函数名) “入口地址” & 取地址运算符(适用于普通变量或数组元素) 实体地址表示法2:间接访问(指针) 适合于地址运算(加减等),实体地址的表示,指针就是变量、数组、函数等的存储地址。,实体地址的一种表示法(便于编程处理)。 指针是一种特殊的数据类型存放的是某个实体的地址值。,变量的“指针” 变量在内存单元的占用的地址(首地址),指针,6.1.3 指针与指针变量,指针变量,指针变量的定义: 存放变量地址的变量称为指针变量,通常在c语言中,所谓“指针”就是指“指针变量”。 从现在开始,我们所说的“指针”除非另加说明,否则均表示“指针变量”。,指针变量,把存放某种变量、数组、函数等的存储地址的变量称为指针变量。,变量的指针和指向变量的指针变量,6.2 变量的指针和指向变量的指针变量,指针变量的定义: 指针变量的引用: 指针变量的赋值: 指针变量的示例:,变量的指针就是变量的地址 用来存放变量地址的变量是指针变量 指针变量用来指向另一个变量 为了表示指针变量和他所指向的变量之间的关系,在c+中用“*”符号表示指向。,变量与指针,如: int *pi; /pi是一个指向int型变量的指针变量 float *pi; /pi是一个指向float型变量的指针变量 char * pc; /pc是一个指向char型变量的指针变量 char (*pa)3; /pa是一个指向一维数组的指针变量 int (*pf)()/pf是一个指向函数的指针变量,该函数返回值为int型 int *pp; /pp是一个指向指针的指针变量 指针变量也可以与普通变量一起定义,如: float a,b,*f;, * ;,6.2.1 指针变量的定义,指针变量的定义,类型名指的是指针变量存放的指针(实体地址)所指向的实体的数据类型,i_pointer2,i_pointer1,i,请看以下变量声明语句 int a,*p1; char b,*p2; a,b 普通变量(存放某个数值或字符) p1,p2 指针变量(存放某个实体的地址),变量声明时,如果变量名前带 *号,表示该变量是个指针变量,指针变量的定义,指针变量的定义,指针的存放(三步曲) 定一个以普通变量,如:int x 定义一个指针变量,如:int *px 将指针变量有所指向,如:px=&x 图示:,指针变量作为函数参数: 练习:,返 回,指针变量的定义,指针变量的定义: 格式: 注释: 指针变量所占空间:一个机器字长() 指针变量只能存放地址 如:p1=100 ,float a,b,*p1,*p2; a=3.5; b=2.7; p1= p2=&b,指针变量的初始化:,1) int a; int *p=,返 回,6.2.2 指针变量的引用,指针变量的引用,代表一 个值,对指针变量施加*运算,则代表取指针所指向的单元的内容。这里,*p与变量i是等价的。 区分:*运算符在不同场合的作用,编译器能够根据上下文环境判别*的作用。 int a,b,c; int * p; (*表示定义指针) p = (*表示乘法运算符),指针变量的引用,指针变量的引用: 两个运算符: 则 &*p = &a = p *&a = a = *p,练习: 若定义 int b=8,*p= 则下面均表示b的地址的一组选项为( )。 a) *p,*&b b) *p,&*b c) p,*&b,&*p d) &*p,p,&b,答案: d,*p:代表8 *&b:先做&b,取b的地址,*(&b)还是表示8 &*b:无实际意义 p:代表b的地址 &*p:先做*p,表示8,&8,表示取8 的地址 &b:取b的地址,注意不同的*p,讨论: 程序中引用变量时, 对指针变量p, 不带*号引用表示? 带*号引用表示?,以下程序中哪些语句是错误的? main() int a,p,*p; a=3; p=3; /*或者 p=a;*/ p= /*或者*p=3*/ ,不带*表示取地址 带*表示指向地址的内容,有关*p的小结,变量声明时,*p表示定义了一个用来存放变量地址而非数据(数值、字符等)的指针变量。 程序中引用时,*p表示取指针变量p所指变量的值。,main() int a,*p1,*p2= ,指针变量赋值(这里要用到取地址运算符“,指针变量的赋值,6.2.3 指针变量的赋值,为指针变量赋初值,无论在哪里都要加取地址运算符,指针变量的赋值,指针变量的赋值:,int *p,a; p=,事例:,返 回,指针变量引用示例,例2:输入a,b两个整数,按先大后小的顺序输出a,b #include void main() int *p1,*p2,*p,a,b; cinab; p1= ,变量声明时,*p表示定义了一个用来存放变量地址的指针变量(并非数据) 程序中引用时,*p表示取指针变量p所指变量的值。(数据),返 回,交换地址,例1:通过指针变量访问整形变量 #include void main() int a,b; int *pointer_1,*pointer_2; a=100;b=10; pointer_1= ,【例6.1】,/程序名为ch06_1.cpp #include void main() int a,b,*p1= /间接访问方式 ,a=20 b=40 a=20 b=40,若输入: 10 20,指针变量作为函数参数,例 int swap(int *p1,int *p2) int temp; temp=*p1; *p1=*p2; *p2=temp; return (*p1,*p2); #include void main() int a,b; int *pointer_1,*pointer_2; cinab; pointer_1= ,返 回,例: int swap(int *p1,int *p2) int temp; temp=*p1; *p1=*p2; *p2=temp; return (*p1,*p2); int exchange(int*q1,int *q2,int *q3) if(*q1 void main() int a,b,c,*p1,*p2,*p3; cinabc; p1=,练习一:,#include using namespace std; void fun(char *c,char d) *c=*c+1;d=d+1; cout*c“,“dendl; void main() char a=a,b=a; fun( 程序运行后的输出结果是_。 a) b,a,b,a b) a,b,a,b c) a,b,a,b d) b,b,a,b,结果:a=13,b=10,结果:d,返 回,#include void main() int a,b=10,*p; p= ,练习二:,以下程序的运行结果是什么? #include void main() float x,y; int *p; x=3.14; p= ,把int *p改为float *p后,结果正确:y=3.140000,错在哪?,返 回,为什么未指向实体的指针是“危险指针”?,一个指针未指向任何实体就被使用,属于”内存盗用”!因为该指针将随意指向内存中某一单元,轻则误取或破坏其他实体的值,重则破坏操作系统的工作。,一个指针变量被声明后,在没有被赋予某个实体地址之前,如果使用它,不仅可能破坏你的程序,而且可能导致计算机操作系统崩溃,出现灾难性的错误。因为它可能指向内存的任何部分。,空指针,空指针: int *p; p=null;,null是什么? 在stdio.h中,定义 #define null 0 所以 p=null; 相当于 p=0;,内存使用常识: 任何c程序的变量在内存中的地址均由操作系统自动分配,不能由编程者通过赋值指定。p=null 表示p不指向任何变量。 内存的低端只供由操作系统使用(相当于政府机关,普通百姓不能使用)。,讨论:以下程序中的*p1,*p2,#include void main(void) int *p1=null,*p2; clrscr(); *p1=100; *p2=200; cout*p1*p2; ,*p1有确定地址,但未指向任何变量,*p2无确定地址,是“危险指针”,在指针p指向某个实体的地址之前,不可对*p进行赋值。否则可能发生意想不到的错误(p随便指向某个单元)。,以下程序对吗?,*p并非就这么简单,*p的含义与p所指的对象有关 如果p被定义成指向普通变量的指针变量,则*p代表该变量的值。 如 int *p,a=5; p= 则*p代表数组a中某个元素。,例如:int a10; int *p; p=a; 或 p= 指针p指向数组的首地址。,6.3 指针与数组,6.3.1 指向数组元素的指针 1. 指向一维数组元素的指针, * ,指向一维数组的指针和指针变量,指向一维数组的指针定义: 如:int a10,*p; p=a; p= 指针变量的运算: 指针与数组表现形式的互换: 数组元素的引用: 用数组名作函数参数: 练习:,返 回,指针变量的运算,例如:变量a的首地址为2000,有: int *p= 值1996,=+/-sizeof()*n,1. 算术运算 主要包括:自加、自减、加n和减n操作。这些算术运算是按c+语言地址计算规则进行的。一般形式:,指针变量的运算,算术运算: 公式: n (n为整数) 含义:使指针变量的指向向下或向上移动n个元素。 移后地址的计算: n *实体数据类型长度,例1: int n; float *p,a3=0.1,0.5,0.7; p=a;n=2; p+n=? *(p+n)=?,例2: #include void main(void ) int a5=0,1,2,3,4; int *p; p= ,指针变量的算术运算,p由数组第一个元 素指向第三个元素,代表数组中第三个 元素,即*(p+n)=0.7,指向数组第二个元素,指向数组第五个元素,指向数组第四个元素,指向数组第一个元素,改变了 初始地 址,未改变 其初始 地址,指针变量的算术运算,指针只有两种算术运算加、减 p+5 p+ p-1 p- 注意加减运算是以实体为单位而不是以字节为单位。 此外,两个指针变量可以相减。即:如果两个指针变量指向同一数组时,两个指针变量值之差是两个指针之间的元素个数。 但两个指针变量相加并无实际意义。,注意:,练习,#include void main(void ) int a10,*p1=a; clrscr(); a+; p1+; ,x,以下程序哪个语句执行时会出错?,(2) 指针变量的关系运算 指针变量的关系运算是指针变量值得大小关系,如大于“”,小于“” ,等于“=”和不等于“!=”,他们都能对两个指针变量存储的地址进行比较。一般来说,指针的关系运算主要用于对数组和循环链表等的处理上。 含义:将两个指针变量内的地址进行比较 如:p=q 1p指向q之前 0p指向q之后 示例:,指针变量的关系运算,指针变量的运算,指针变量的关系运算: 含义:将两个指针变量内的地址进行比较 如:p=q 1p指向q之前 0p指向q之后 示例: 指针运算符的混合运算与优先级: 同级运算符:+,- -,*,& 同级结合性:自右向左 示例:,返 回,指针变量的关系运算、混合运算,关系运算: #include void main() int a5=1,2,3,4,5; int *p, *p1; p1= ,混合运算: 1)b=*p+; 2)b=*+p; 3)b=(*p)+; 4)b=+*p;,b=*p; p+;,+p; b=*p;,b=*p; p所指向变量的值+1;,b= p所指向变量的值+1;,返 回,【例6.2】统计输入字符串的字符个数,/程序名为ch06_2.cpp #include void main( ) char str80; char *p; coutstr; p=str; while(*p!=0) p+; cout“the number of characters in this string :“p-strendl; ,指针变量的关系运算、混合运算,结果,enter a string (less than 80 characters): absdef the number of characters in this :6,指针变量的关系运算、混合运算,写出运行结果,#include #include void main( ) int a=3,4,5,6,7,8,9,*p; p=a;*(p+3)+=2; cout*p“,”*(p+3); ,结果为:3,8,指针的逻辑比较,指针变量指向同一个对象(如数组)的不同单元地址时,才可以进行比较。地址在前者为小。 任何指针变量或地址都可以与null作相等或不相等的比较。如 if(p=null),#include #include fun(char *w,int n) char t,*s1,*s2; s1=w; s2=w+n-1; while (s1s2) t=*s1+; *s1=*s2-; *s2=t; void main(void) char *p; p=“1234567“; fun(p,strlen(p); coutp; ,结果:1711717,【注意】对*s1+,因*与+同级,且自右至左结合,所以等价于*(s1+),执行时是先做*s1,后做s1+ 。 p215,变量追踪: 首先通过fun函数将p数组传递给 w数组,w数组为“1234567”,函 数strlen测试长度得7传递给n,使 n=7,则s1指向1s2指向7,由于1 =s2,结果为1711717,看看两个例子,#include void main( ) int a,b=10,*p; p= ,#include void main(void) int *p,a12=1,2,3,4,5; p=a; for ( ;*p5;p+) cout*p; ,结果:a=13,b=10,结果:1234,指针与数组表现形式的互换,地址的表示: p=&a0=a p+1=&a1=a+1 p+2=&a2=a+2 p+i=&ai=a+i,数组元素的表示: *(p)=a0=*(a) *(p+1)=a1=*(a+1) *(p+2)=a2=*(a+2) *(p+i)=ai=*(a+i) 变址运算符: ai=*(a+i) pi=*(p+i),返 回,数组元素的引用,有四种方法:,数组下标法:ai,地址法:*(a+i),指针变量法:*(p+i),pi,例:顺序输入10个数,要求倒序输出,返 回,数组元素引用的示例,数组下标法: for(i=0;iai; for(i=9;i=0;i-) cout*p+; for(p=a+9;p=a;p-) cout*p;,地址法: for(i=0;i*(a+i); for(i=9;i=0;i-) coutpi; for(i=9;i=0;i-) coutpi;,返 回,用数组名作函数参数的示例,示例: 例9.7:将数组按相反顺序存放 例9.8:从10个数中找出其中最大值和最小值 总结:,返 回,示例 9.7,#include void inv(int * x,int n) int *p,temp,*i,*j,m=(n-1)/2; i=x; j=x+n-1; p=x+m; for(;i=p;i+,j-) temp=*i; *i=*j; *j=temp; return; void main( ) int i,a10=3,7,9,11,0,6,7,5,4,2; cout“the original array:n“; for(i=0;i10;i+) coutai“ “; coutendl; inv(a,10); cout“the array has been inverted:n“; for(i=0;i10;i+) coutai“ “; coutendl; ,将数组按相反顺序存放,示例 9.8,#include int max,min; void max_min (int *array,int n) int *p,*array_end; array_end=array+n; max=min=*array; for(p=array+1;pmax) max=*p; else if(*p*p; p=number; max_min (p,10); coutmax“ “minendl;,从10个数中找出其中最大值和最小值,练习:,#include fun(int *s,int n1,int n2) int i,j; i=n1;j=n2; while(ij) *(s+i)+=*(s+j);*(s+j)+=*(s+i); i+;j-; void main() int a6=2,3,4,5,6,7,i,*p=a; fun(p,0,3); fun(p,1,4); fun(p,3,5); for(i=0;i6;i+) cout“%d ”,*(a+i); cout“n”); ,7 13 23 42 19 49,变量追踪 第一次:2 3 4 5 6 7,s指向2,i=0;j=3; 01,退出循环 第二次:7 7 11 12 6 7;s指向7,i=1; j=4; 12, 退出循环 第三次:7 13 23 35 19 7;i=3;j=5;35;35+ =7;7+=42;i+;j-;数组变为:7 13 23 42 19 49;4=4;数组变为:7 13 23 42 19 49,运算后注意值的变化,指向数组的指针练习一:,#include main() int a=3,4,5,6,7,8,9,*p; p=a;*(p+3)+=2; cout*p,*(p+3); ,结果为:3,8,返 回,指向数组的指针练习二:,若定义 float b18,*p=且数组的首地址为100h, 则 p+15表示的地址为 ( )。 a) 115h b) 10fh c) 160h d) 13ch,选d,返 回,指向数组的指针练习四:,#include void main( )int a=1,3,5,7,9,b=2,4,6,3,7,c,d=1,*p=a,*q=b; p+=3;q+=2; c=(*p-)/(*q)+5; 7/6+5=6 d+=*p; 1+5=6 coutcendl; coutdendl; ,运行结果为:6 6,例如:int a23; int *p= 说明:c+规定二维数组a中第i行地址用a+i或&ai表示,并且行地址的值与行首地址的值是相同的,即: a+i=&ai=ai=&ai0,2. 指向二维数组元素的指针, * ,3.指向一维数组的指针 一般格式:, (* )数组第二维长度,例如:int a23; int (*p)3; p=a; 所以:aij的地址有4种表示方式: ai+j、*(a+i)+j、&ai0+j、&aij 或: pi+j、*(p+i)+j、&pi0+j、&pij,指向多维数组的指针和指针变量,序: 回忆一维数组的地址及其元素的表示方法,二维数组的地址 指向多维数组的指针变量,地址表示:&a0 &a1 &a2 &a3 &a4 a a+1 a+2 a+3 a+4 p p+1 p+2 p+3 p+4,内容表示 ai *(a+i) *(p+i)=pi,二维数组的地址,注: 将二维数组看成多个一维数组,每个一维数组又包含若干个元素 地址及值的表示法: 表示法总结:见书 示例: 练习:,返 回,二维数组地址及值的表示法,图示:,&ai0 &ai1 &ai2 &ai3 &ai4,a0 a1 a2,*(a+0) *(a+1) *(a+2),&a0 &a1 &a2,各行首地址,ai+0 ai+1 ai+2 ai+3 ai+4,*(a+i)+0 *(a+i)+1 *(a+i)+2 *(a+i)+3 *(a+i)+4,各元素地址,c规定:a0,a1,a2代表抵0,1,2行首地址, *(p+i)=pi *(a+i)=ai,一维数组中a,a+1,a+2代表每个元素的首地址, *(a+i)=ai a+i=&ai,c规定:具体到每个元素的地址 ai+j, *(a+i)代表第i行首地址 *(a+i)+j代表第i行第j列元素地址,a a+1 a+2,&aij表示地址 aij表示其内容,ai+j表示地址 *(ai+j)表示其内容,*(a+i)+j表示地址 *(*(a+i)+j)表示其内容,二维数组地址表示法示例,例9.11 #include void main( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23; couta,*a; couta0*(a+0); cout ,#include void main() int a33=1,2,3,4,5,6,7,8,9; int (*p)3,i; p=a; for (i=0;i3;i+) couta+iendl; cout ,#include void main() int a33=1,2,3,4,5,6,7,8,9; int (*p)3,i,j; p=a; for (i=0;i3;i+) for(j=0;j3;j+) cout*(*(a+i)+j)endl; ,#include void main() int a33=1,2,3,4,5,6,7,8,9; int (*p)3,i; p=a; for (i=0;i9;i+) cout*(p+i)endl; ,#include void main() int a33=1,2,3,4,5,6,7,8,9; int (*p)3,i,j; p=a; for(i=0;i3;i+) for(j=0;j3;j+) cout*(*(p+i)+j); ,2 3 5 6 7 8 9,输出每行以及每个元素的地址,输出每个元素,输出每个元 素的地址,依次输出 每个元素,类似,指向多维数组的指针变量,指向数组元素的指针变量 示例及图示: 指向由m个元素组成的一维数组的指针变量 定义:()下标 例:int (*p)4 含义:p为一指针变量,指向一包含4个元素的一维数组。 图示及总结: 示例: 练习: 多维数组的指针做函数参数 例9.14,9.15,返 回,指向数组元素的指针变量示例,例:9.12 #include void main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for(p=a0;pa0+12;p+) if(p-a0)%4=0) coutendl; cout*p“ “; ,图示:,指向一维数组的指针变量图解,图示: 1),总结: p+i=ai *(p+i)+j=&aij *(*(p+i)+j)=aij *(p+i)=p+i=ai(表第i行第0列元素地址) 但:*(p+i)+j(p+i)+j,2),p的内容 即(*p),某元素地址 *(p+i)+j,返 回,指向一维数组的指针变量的示例,例:9.13 #include void main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int(*p)4,i,j; p=a; cinij; cout*(*(p+i)+j)“ “; ,练习一:,若有以下定义和语句,且0i4,0j3,则不能访问a数组元素的是 。 int i, (*p)3; int a 3=1,2,3,4,5,6,7,8,9,10,11,12; p=a; a)*(*(a+i)+j) b)pij c)(*(p+i)j d)pj+j,答案:d (pj+j是个地址),练习二:,#include void main() int a33=1,2,3,4,5,6,7,8,9; int (*p)3,i,j; p=a; for(i=0;i3;i+) for(j=0;j3;j+) cout*(*(p+i)+j); ,结果:1 2 3 4 5 6 7 8 9,练习三:,#include void main() char a310=“abc“,“123456“,“abcde“; char (*p)10; p=a; coutp+1“ “*(p+1)endl; cout*(*(p+1)“,“; cout*(*(p+2)+1)“,“; cout*(*(p+2)+2)endl; ,结果:数组第二行首地址,123456 1,b,c,多维数组的指针做函数参数示例1,#include void main() void average(float*p,int n); void search(float(*p)4,int n); float score34=65,67,70,60,80,87,90,81,90,99,100,98; average(score,12); search(score,2); ,void average(float *p,int n) float *p_end; float sum=0,aver; p_end=p+n-1; for(;p=p_end;p+) sum=sum+(*p); aver=sum/n; cout“average=“averendl; void search(float(*p)4,int n) int i; cout“the score of no.2 are:n“; for(i=0;i4;i+) cout*(*(p+n)+i)“ “;,任何一种数据类型的指针所赋的值都是内存的地址值,但是不同类型的对象取地址的方式却有以下的不同点: 一般变量的地址,用取地址符“ 这表明ps是一个指向函数的指针,它指向函数sum在内存的入口地址。,6.2.4 指针变量作为函数参数,在c+中,有以下3种类型的指针可以作为函数的参数。 一般对象(含变量)的指针作为函数的参数; 数组指针(含字符串的指针)作为函数的参数; 函数的指针作为函数的参数;,【例6.3】一个变量的指针作为函数的参数的应用,/程序名为ch06_3.cpp #include void change(int *p1,int *p2); void main( ) int a,b; a=3; b=4; cout“a=“a“,b=“bendl; change( ,结果,a=3 b=4 a=8 b=5,6.3.2 通过指针引用数组元素,如:ai或pi 2)指针法 如:*(a+i)或*(p+i),下标,1. 通过指向数组元素的指针引用一维数组元素 一般有以下两种方法: 1)下标法,*(数组名/指针变量名+下标),根据数组元素存储的连续性以及指针的运算规则,可以得出以下结论: 1) p+1表示指向数组中的下一个元素。 2) 若p=&a0,i是一个整数,那么: p+i或a+i就是ai的地址(i不能超过数组的最大长度) *(p+i)或*(a+i)代表数组元素ai。 ai也可以写成pi,二者是等价的。,【例6.4】用指针法输入、输出数组元素,#include “iostream.h“ const int n=5; void main() int an,*p; p=a; for (p=a;p*p; p=a; for (int i=0;i5;i+) cout*(p+i)“ “; coutendl; ,结果,(输入) 10 20 30 40 50 (输出) 10 20 30 40 50,使用指针法时有以下几个问题需要注意:,用指针引用数组元素是注意地址不要越界。 注意指针的运算。若:p=&ai,则有: 1) p+使p指向数组中下一个元素ai+1,在执行*p,表示取出ai+1的值。 2)*p+等价与*(p+),因为“+”和“*”的优先级相同。其结合方向是从右向左。该操作的含义是先执行*p,在执行p+,使p指向下一个元素,这个式子相当于ai+. 3) (*p)+表示p所指向的元素值加1,而p的值不变。 4) *(+p)相当于a+i。表示先执行+p,使p指向下一个元素,在进行“*”运算。,【例6.5】采用指针法,输出二维数组中所有元素的值,#include void main() static int a35=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15; int *p; for (p=a0;pa0+15;p+) cout*p“ “; coutendl; 结果: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15,2. 通过指向数组元素的指针引用二维数组元素,【例6.6】,#include void main() static int a35=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15; int *p= 结果: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15,3.通过指向一维数组的指针引用二维数组元素,指向一维数组的指针等同于二维数组名,他们的区别就是前者是变量,后者是常量。 若:int a23; int (*p)3; 有p=a; c+规定数组a的第i行和第j列元素aij的值有下面4种表示方法: *(ai+j)、*(*(a+i)+j)、*(&ai0+j)、aij 或 *(pi+j)、*(*(p+i)+j)、*(&pi0+j)、pij,【例6.7】,#include void main() static int a35=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15; int (*p)5; p=a; for (int i=0;i3;i+) for (int j=0;j5;j+) cout*(*(p+i)+j)“ “; coutendl; 结果: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15,6.3.3 数组名作函数参数,数组名可以用作函数的形参和实参,数组名代表数组首地址。 实参和形参一般有如下几种对应情况: 形参和实参都用数组名; 实参用数组,形参用指针变量; 实参、形参都指针变量; 实参为指针变量,形参为数组名,【例6.8】,#include float average(int *array,int n); void main() int a10=1,2,3,4,5,6,7,8,9,10; float aver; aver=average(a,10); coutaverendl; float average(int *array,int n) float sum=0; for (int i=0;i10;i+) sum+=*array; array+; return (sum/n); 结果:5.5,6.4 指针与字符串,6.4.1 字符串的表示形式 在c+程序中,字符数组和字符型指针都可以实现对字符串的存储和运算。 用数组的形式表示一个字符串; 如:char string=“i love china”; 其中,string为数组名,代表字符数组的首地址。 用数组型指针指向一个字符串。 如:char * str=“i love china”; 其中,str是一个字符指针变量,而“i love china”是一个字符串常量,str指向它的首地址。输出时,系统先输出str指向的第一个字符数据,然后使str自动加1。,使之指向下一个字符,然后在输出一个字符一直到遇到0为止。,字符数组和字符指针的区别:,字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是字符串的首地址,决不是将字符串放在字符指针变量中; 在定义一个数组中,在编译时即以分配存储单元,有确定的地址,而字符指针变量在运行时才能有确定的地址。,【例6.9】,#include void main() char source=“copy a string“; char destin20; int i; for (i=0;*(source+i)!=0;i+) *(destin+i)=*(source+i); *(destin+i)=0; cout“source string is: “sourceendl; cout“destin string is: “; for (i=0;destini!=0;i+) coutdestini; coutendl;,结果:,source string is: copy a string destin string is: copy a string,【例6.10】,#include float average(int *array,int n); void main() char source=“copy a string“; char destin20,*p1,*p2; p1=source;p2=destin; int i; for (;*p1!=0;p1+,p2+) *p2=*p1; *p2=0; cout“source string is: “sourceendl; cout“destin string is: “; for (i=0;destini!=0;i+) coutdestini; coutendl;,6.4.2 字符串指针作函数参数,#include int mystrlen(char string) int len=0; while (stringlen!=0) len+; return len; void main() char string80; coutstring; cout“length of string is:“mystrlen(string)endl; ,【例6.11】测试字符串的长度,结果:,input a string: nobody length of string is: 6,#include “iostream.h“ int mystrlen(char* str) int len=0; for(;*str!=0;str+) len+; return len; void main() char string80; coutstring; cout“length of string is: “mystrlen(string)endl; 结果同上例,【例6.12】,把首地址传给字符指针str,6.5 指向函数的指针,6.5.1 用函数指针变量调用函数 注意: “类型名”是指被指向的函数返回值类型,“形参表”中需列出被指向函数所要求得各参数(或参数类型),如果被指向函数是无参函数,那么形参为空(但括号不能少) 指针变量两侧的括号用于指针变量先于“*”结合,以次说明它是一个变量名而不是函数名,然后再与后面的括号结合,表示该指针所指向的是函数而不是普通变量。 赋值方法很简单,只需将程序中一个具体的函数名赋给该指针变量即可。, (*)(形参表);,#include int test(int a); void main() int (*pf)(int a); pf=test; coutpf(100)endl; int test(int a) return a; 结果: 100,【例6.13】,6.5.2 用指向函数的指针作为函数参数,函数指针变量的用途通常是把指针作为参数传递给其他函数,通过这种方式传递函数的地址,从而实现一个函数作为另一个函数的参数,目的是设计出更通用、更强大的函数,#include “iostream.h“ int max(int a,int b) return ab?a:b; int min(int a,int b) return axy; cout“max=“max_min(max,x,y)endl; cout“min=“max_min(min,x,y)endl;,【例6.14】,结果:,input two integer numbers! 4 9 max=9 min=4,6.6 指针数组和指向指针的指针,6.6.1 指针数组的概念 指针数组:一个数组,如果其数组元素均为指针,那么此数组为指针数组。 一维指针数组的定义: 例如:int *p4; 同理,二维指针数组的定义: 例如:int *ptr23;, *数组长度;, *第1维数组长度第2维数组长度;,#include “iostream.h“ #include “string.h“ void main() char *weather12=“frost“,“hail“,“snow“,“thunder“,“wind“,“mist“,“cloud“,“haze“,“rain“,“downpour“,“shower“,“storm“; int i,j,k; char *q; for (i=0;i0) k=j; q=weatheri;weatheri=weatherk; weatherk=q; for (i=0;i12;i+) coutweatheri“ “; ,【例6.15】,结果:,cloud downpour frost hail haze mist rain shower snow storm thunder wind,6.6.2 指针的指针,指针的指针:指向指针变量的指针变量。指针的指针存放的是指针变量地址. 指针变量的指针变量(指针的指针)的定义: 类型 *指针变量名; 例如:int x=1; int *p,*pp; p=,#include “iostream.h“ #include “string.h“ void print_char(char *a,int len); void main() char *fruits=“ apple“,“ pear“,“ apricot“,“ peach“,“ grape“,“ banana“,“ pineapple“; char *p=fruits; cout*p“t“*(p+1)“t“*(p+2)endl; int nu

温馨提示

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

评论

0/150

提交评论