1.24k likes | 1.38k Views
第六章 指针、引用和动态空间管理. 6.1 指针的概念 6.1.1 指针的概念 6.1.2 指针变量的定义和初始化 1 .指针表示内存空间的地址。指针类型定义以*标识。 例: int* // 整型指针 char* // 字符指针 double*//double 型指针 . 第六章 指针、引用和动态空间管理. 2 .指针变量定义 例: int* ip; char* cptr; int* iptr1,*iptr2;. 第六章 指针、引用和动态空间管理. 3 .建立指针 (1) 建立指针包含指针变量定义和给指针赋初值 ( 地址 ) 。
E N D
第六章 指针、引用和动态空间管理 6.1 指针的概念 6.1.1 指针的概念 6.1.2 指针变量的定义和初始化 1.指针表示内存空间的地址。指针类型定义以*标识。 例:int* //整型指针 char* //字符指针 double*//double型指针
第六章 指针、引用和动态空间管理 2.指针变量定义 例:int* ip; char* cptr; int* iptr1,*iptr2;
第六章 指针、引用和动态空间管理 3.建立指针 (1)建立指针包含指针变量定义和给指针赋初值(地址)。 (2)&操作符可取变量地址,指针变量用于存放地址。
第六章 指针、引用和动态空间管理 例:int* iptr; int icount=18; iptr=&icount;//指针赋值 该例等价与
第六章 指针、引用和动态空间管理 例:int icount=18; int* iptr=&icount;//指针的初始化 内存表示:
第六章 指针、引用和动态空间管理 4.间接引用指针 操作符*可取指针变量所指单元内容,称为间接引用指针。
第六章 指针、引用和动态空间管理 例:#include<iostream.h> void main() { int * iptr; int icount=18; iptr=&icount; cout<<*iptr<<endl; *iptr=58; cout<<*iptr<<endl; } 结果:18 58
第六章 指针、引用和动态空间管理 5.指针变量地址:指针变量也具有内存地址。 例:#include<iostream.h> void main() { int icount=18; int* iptr=&icount; *iptr=58; cout<<icount<<endl; cout<<iptr<<endl; cout<<&icount<<endl; cout<<*iptr<<endl; cout<<&iptr<<endl; }
第六章 指针、引用和动态空间管理 结果:58 0x0067fe00 0x0067fe00 58 0x0067fefc 内存表示:
第六章 指针、引用和动态空间管理 例:int icount=58; int* iptr=&icount; 则 icount //整型变量 iptr //指针变量 &icount //整型变量icount地址
第六章 指针、引用和动态空间管理 &iptr //指针变量iptr地址 *icount //错误 *iptr //指针变量iptr所指单元内容 6.*(取内容)和&(取地址)为互逆操作。
第六章 指针、引用和动态空间管理 6.1.3 const指针 1.指向常量的指针:在指针定义语句的类型前加const,表示指针指向的数据为常量。
第六章 指针、引用和动态空间管理 例:const int a=78; const int b=28; int c=18; const int * pi=&a; //int const * pi=&a; *pi=58; //错误,*pi为常量 pi=&b; *pi=68; //错误,*pi为常量
第六章 指针、引用和动态空间管理 pi=&c; *pi=88; //错误,*pi为常量 c=98; 结论:const int * pi=&a;(或int const * pi=&a;)中,*pi为常量,pi为变量,故*pi不能为左值。
第六章 指针、引用和动态空间管理 2.指针常量:在指针定义语句的指针名前加const,表指针本身为常量。
第六章 指针、引用和动态空间管理 例:char * const pc="asdf"; pc=“dfgh”;//错误,pc为常量 *pc='b'; *(pc+1)='c'; *pc++=‘y’; //错误,pc为常量 结论: int * const pi=&a;中,*pi为变量,pi为常量,故pi不能为左值。
第六章 指针、引用和动态空间管理 3.指向常量的指针常量 结论: const int * const pi=&a;中,*pi、pi均为常量,故均不能作为左值。
第六章 指针、引用和动态空间管理 例:const int ci=7; int ai; const int * const cpc=&ci; const int * const cpc=&ai; cpi=&ai; //错误,cpi为常量 *cpi=39; //错误,*cpi为常量 ai=39;
第六章 指针、引用和动态空间管理 6.2 指针运算 6.2.1 赋值(=) • 同类型指针之间可相互赋值。 • 任何类型的指针可赋值给void指针,反之不行。 例:char c=‘x’,*s=&c; void * p1,* p2=Null; p1=s;//对 s=p2;//错
第六章 指针、引用和动态空间管理 6.2.2 取地址(&) • 单目运算符&可取变量的地址。 例:int k,*p; p=&k; k p
第六章 指针、引用和动态空间管理 6.2.3 取内容(*) • 单目运算符*可取指针所指的内存单元内容。 例:int *pd,d; pd=&d; *pd=99; cout<<*pd<<‘ ‘<<endl; d pd 99
第六章 指针、引用和动态空间管理 6.2.4 判断一指针是否为空指针(==或!=)。 例:如果p是空指针,则… if(p==0)… if(p==Null)… if(!p)… 例:如果p不是空指针,则… if(p!=0)… if(p!=Null)… if(p)…
低地址 p1 高地址 p2 第六章 指针、引用和动态空间管理 6.2.5 计算两地址间数据单元的个数(-)。 • 计算两地址间存储单元的个数。 • 一般将高地址指针作被减数,且其数据不计算在内。 例:int n,m[12],*p1=&m[5],*p2=&m[10]; n=p2-p1;//n==5
第六章 指针、引用和动态空间管理 6.2.6 指针移动 1. 移动n个单位:操作符+、 -、 +=和 -=。 指针向后(高地址)移动n个单位:指针表达式+n或指针表达式+=n。 指针向前(低地址)移动n个单位:指针表达式-n或指针表达式-=n。 例:见书。
第六章 指针、引用和动态空间管理 2. 移动1个单位:操作符++(前增1)、 ++(后增1) -- (前减1)和-- (后减1) 。 指针向后(高地址)移动1个单位:指针变量++或++指针变量。 指针向前(低地址)移动1个单位:指针变量--或--指针变量。
第六章 指针、引用和动态空间管理 例:int k,*pk=&k; cout<<endl<<++pk; cout<<endl<<pk; 结果是两个相同的地址。 例:int k,*pk=&k; cout<<endl<<pk++; cout<<endl<<pk; 结果是两个不相同的地址。
第六章 指针、引用和动态空间管理 6.2.7 指针表达式的副作用 1.表达式的副作用:表达式计算过程中,若参与运算的变量的值发生了改变,称此表达式具有副作用。如i+j++。 2.表达式的副作用产生的原因是使用了具有副作用的操作符,包括: (1)赋值(=) (2)复合赋值(+=,-=,*=,/=等等) (3)前增1和前减1(++,--) (4)后增1和后减1(++,--)
第六章 指针、引用和动态空间管理 3.对指针表达式 具有副作用的操作符,包括: (1)赋值(=) (2)复合赋值(+=,-=,*=,/=等等) (3)前增1和前减1(++,--) (4)后增1和后减1(++,--) 无副作用的操作符,包括: (1)取地址(&) (2)间接引用(*) (3)其它如+,-,==等
第六章 指针、引用和动态空间管理 4.对指针表达式,设p为指针变量。 (1)前增量++p,前减量—p,间接引用*p,赋值及复合赋值的结果仍为左值。 (2)后增量p++,后减p--,取地址&k及由p构成的算术表达式和关系表达式的结果不能作为左值。
第六章 指针、引用和动态空间管理 例:设p为指针变量。 ++(++p) //对 (p++)++ //错 --p+=&k //对 p--+=&k //错 ++p++ //错 (++p)++ //对 ++(p++) //错 p++-=3 //错 (p+3)++ //错 ++(p+3) //错 ++++p //对 p++++ //错
第六章 指针、引用和动态空间管理 6.2.8 指针类型的强制转换 (类型修饰符*) 指针表达式 6.2.9 指针操作符的综合运用 例:见书。
第六章 指针、引用和动态空间管理 6.3 指针与数组 6.3.1 一维指针与数组 1.指针的加减运算即指针的移动操作(以内存单元为单位)。 2.一维数组名是首元素地址。
a[0] a a[1] a+1 a[2] a+2 a[3] a+3 a[4] a+4 第六章 指针、引用和动态空间管理 例:int a[5];
a[0] a[1] a[2] … … … … a[9] 第六章 指针、引用和动态空间管理 例:int a[10]; int* pa=a;//int* pa=&a[0]; a pa
第六章 指针、引用和动态空间管理 第i个元素(四种表示): a[i] *(a+i) p [i] *(p+i) 第i个元素地址(四种表示) : &a[i] (a+i) &p[i] (p+i)
第六章 指针、引用和动态空间管理 例:#include<iostream.h> void main() { int iArray[10]; int sum=0; int* iptr=iArray;// 数组名是首元素地址 for(int i=0;i<10;i++) iArray[i]=i*2; for(int index=0;index<10;index++) { sum+=*iptr; iptr++; } cout<<”sum is”<<sum<<endl; }
第六章 指针、引用和动态空间管理 上例内存表示:
第六章 指针、引用和动态空间管理 3.一维数组名是首元素地址,但数组名是指针常量,不能作为左值。 例:见书。 4.数组指针:指向数组且与数组名等价的指针。
第六章 指针、引用和动态空间管理 例:int a[100]; int* iptr=a; iptr称为数组指针。 此时iptr++ //正确,因iptr为指针变量 a++ //错误,因a为指针常量
第六章 指针、引用和动态空间管理 例:对数组的求和运算,有以下5种方法。 #include<iostream.h> int s1,s2,s3,s4,s5; int a[]={1,4,7,10,13,16,19,22,25}; int* iptr;
第六章 指针、引用和动态空间管理 void main() { int size,n; size=sizeof(a)/sizeof(*a); //size=sizeof(a)/sizeof(a[0]);
第六章 指针、引用和动态空间管理 for(n=0;n<size;n++) s1+=a[n];//方法1 iptr=a; for(n=0;n<size;n++) s2+=*iptr++;//方法2 iptr=a; for(n=0;n<size;n++) s3+=*(iptr+n);//方法3
第六章 指针、引用和动态空间管理 iptr=a; for(n=0;n<size;n++) s4+=iptr[n];//方法4 for(n=0;n<size;n++)s5+=*(iArray+n);//方法5
第六章 指针、引用和动态空间管理 cout<<s1<<endl <<s2<<endl <<s3<<endl <<s4<<endl <<s5<<endl; }
第六章 指针、引用和动态空间管理 6.3.2 多维数组与指针 1.二维数组的数组名是首行地址。 例:int b[5][2]; int (*pb)[2]=b; 此时,pb与数组名b等价,称pb是与数组b等价的数组指针。
b b[0][0] b[0][1] b[1][0] b[1][1] b+1 b[2][0] b[2][1] b+2 b[3][0] b[3][1] b+3 b[4][0] b[4][1] b+4 第六章 指针、引用和动态空间管理 内存表示:
第六章 指针、引用和动态空间管理 数组b的第i行第j列元素可表示为: pb[i][j] b[i][j] *(b[i]+j) *(*(b+i)+j) *(pb[i]+j) *(*(pb+i)+j) 相应地,有数组b的第i行第j列元素地址的表示方法。 以上转换要点:a[i]等价与*(a+i)
第六章 指针、引用和动态空间管理 • 由于b[0]可看成具有2个元素的一维整形数组,故其数组名b[0]即首元素地址&b[0][0],b[0]+1即&b[0][1]。 同理 b[1]即&b[1][0],b[1]+1即&b[1][1]。 b[2]即&b[2][0],b[2]+1即&b[2][1]。 b[3]即&b[3][0],b[3]+1即&b[3][1]。 ……
b b[0][0] b[0][1] b[1][0] b[1][1] b+1 b[2][0] b[2][1] b+2 b[3][0] b[3][1] b+3 b[4][0] b[4][1] b+4 第六章 指针、引用和动态空间管理 b[0] b[0]+1 b[1] b[1]+1 内存表示:
第六章 指针、引用和动态空间管理 例:设计函数show_matrix,它显示参数传来的任意规格的整形二维数组。 #include<iomanip.h> void show_matrix(int* array,int row,int col,int width) { for(int i=0;i<row;i++) { cout<<endl; for(int j=0;j<col;j++) cout<<setw(width)<<*(array+i*col+j); } } void main() { int s[][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; show_matrix(s[0],4,3,5); //&s[0][0]或(int*)s cout<<endl; }