C++第6章指针人民邮电出版北科大.ppt

上传人:za****8 文档编号:15798716 上传时间:2020-09-06 格式:PPT 页数:95 大小:1.95MB
返回 下载 相关 举报
C++第6章指针人民邮电出版北科大.ppt_第1页
第1页 / 共95页
C++第6章指针人民邮电出版北科大.ppt_第2页
第2页 / 共95页
C++第6章指针人民邮电出版北科大.ppt_第3页
第3页 / 共95页
点击查看更多>>
资源描述
第六章 指针和引用,第六章 指针,6.1 指针的概念 6.2 指针与数组 6.3 指针和函数 6.4 动态存储分配 6.5 引用,6.1 指针的概念,为什么要引入指针的概念? 指针可以有效地表示复杂数据结构,如队列、栈、链表等。 指针能象汇编语言一样处理内存地址,为动态内存分配提供支持。 指针可实现对数组和字符串的方便使用,提高某些子程序的效率。,6.1 指针的概念,关于指针的原则 学习原则 一定要学会 其实通常的应用很简单 使用原则 永远要清楚每个指针指向了哪里,2020/9/6,4/82,2020/9/6,5/82,main() int a=5; int b; float x=3.5; ,变量的两个物理意义,6.1.1 指针和指针变量,变量的内容,变量的内容,变量的内容,变量的地址,变量的地址,变量的地址,变量的地址和变量的内容,变量的地址 变量所分配存储空间的首地址 变量的内容 变量在所分配的存储空间中存放的数据,2020/9/6,6/82,2020/9/6,7/82,main() int a,b; float x=35; a=5; b=a+3; ,1001 1002 1003 1004 1015 1016 1017 1018,a b,利用变量名存取数据的方式称为“直接存取”方式。,直接存取和间接存取,8,2020/9/6,8/82,C 语言还提供了对内存单元的“间接存取”方式,5,1001,3,main( ) int a=5,b=3,*p; p = ,变量的地址称为变量的指针 存放地址的变量称为指针变量 p指向c,c为p所指向的目标变量。,直接存取和间接存取,8,2020/9/6,9/58,int main() float x, *p1=NULL; float *p2= ,2000,6.1.2 指针变量的定义,NULL,指针变量初始化,数据类型 * 指针变量名,2012,2020,6.1.2 指针变量的定义,说明: 当把一个变量的地址作为初值赋给指针时,该变量必须先给以定义,且该变量的数据类型必须与指针的数据类型一致 也可把一个已初始化的指针值作为初值赋予另一指针 也可通过初始化定义某种类型的空指针,2020/9/6,10/82,2020/9/6,11/82,6.1.3 指针的基本运算,取地址运算,间接存取运算* *指针变量或目标变量的地址 int i, *p;p = ,pa指针变量 *pa指针pa的目标变量 int main() int a, b, *p1, *p2, *p; p1= ,【例6.1】输入a、b两个整数,使用指针变量按大小顺序输出这两个整数。,6 8 a=6,b=8 max=8,min=6,6.1.3 指针的基本运算,2020/9/6,16/82,方法2:利用指针变量直接改变目标变量的值。#include using namespace std; int main() int a, b, t, *p1, *p2; p1= ,6 8 a=8,b=6 max=8,min=6,6,6.1.3 指针的基本运算,int main() int a10=10,20,30,40,50,60,70,80,90,100; int i, *ptr, *p1, *p2; ptr=a; for (i=0;i10;i+) (*ptr)+; ptr+; p1=p2=a;p1+=5; p2+; cout“a=”aendl; cout“p1=”p1”,*p1=”*p1endl; cout“p2=”p2”, *p2=”*p2endl; cout“p1-p2=”p1-p2endl; cout“*(p1+2)=”*(p1+2) “,(*p1)+2=”(*p1+2)endl; return 0; ,2020/9/6,17/82,指针的算术运算,6.1.3 指针的基本运算,指针加减运算要点: 两个指针变量不能做加法运算。 只有当指针变量指向数组时,并且只有当运算结果仍指向同一数组中的元素时,指针的加减运算才有意义。 指针加减运算的结果不以字节为单位,而是以数据类型的大小(即sizeof(类型))为单位。 只有当两个指针变量指向同一数组时,进行指针相减才有实际意义。 *(p1+n)与(*p1)+n是两个不同的概念。,ptr,31,21,11,41,51,61,71,81,91,101,2020/9/6,18/82,指针的关系运算, 指向同一数组的两个指针可以进行关系运算 指针与一个整型数据比较是没有意义的,不同类型指针变量之间的比较是非法的。 NULL可以与任何类型指针进行=、!=的运算,用于判断指针是否为空指针。,6.1.3 指针的基本运算,6.1.4 指针作为函数参数,2020/9/6,19/82,【例6.3】从键盘任意输入两个整数,编程将其交换后再重新输出。,2020/9/6,20/82,void swap(int *p1,int *p2 ) int temp; cout调用中交换前:*p1=*p1 ,*p2=*p2endl; temp=*p1; *p1=*p2; *p2=temp; cout调用中交换后:*p1=*p1 ,*p2=*p2endl; ,int main( ) int x1,x2; cinx1x2; cout1: x1=x1 ,x2=x2endl; swap( ,void swap(int x,int y) int temp; cout“调用中交换前: x=” x“,y=”yendl; temp=x; x=y; y=temp; cout调用中交换后:x=“ x,y=yendl; ,方法 1,方法 2,int main( ) int x1,x2; cinx1x2; cout1: x1=x1 ,x2=x2endl; swap(x1,x2); cout2:x1=x1,x2=“ x2endl; return 0; ,例6-3 编写函数实现两数的互换,20 10 1: x1=20,x2=10 调用中交换前:x=20,y=10 调用中交换后:x=10,y=20 2: x1=20,x2=10,20 10 1: x1=20,x2=10 调用中交换前:*p1=20,*p2=10 调用中交换后:*p1=10,*p2=20 2: x1=10,x2=20,2020/9/6,21/82,主调函数,被调函数,int main( ) int x1,x2; cinx1x2; cout1: x1=x1 ,x2=x2endl; swap(x1,x2); cout2:x1=x1 ,x2=“x2endl; return 0; ,void swap(int x,int y) int temp; cout调用中交换前:x=“ x,y=yendl; temp=x; x=y; y=temp; cout调用中交换后:x=“ x,y=yendl; ,20,20,x1,x2,实 参,形 参,10,10,方法 1,x,y,2020/9/6,22/82,主调函数,被调函数,int main( ) int x1,x2; cinx1x2; cout1: x1=x1 ,x2=x2endl; swap( ,void swap(int *p1,int *p2 ) int temp; cout调用中交换前:*p1=“ *p1,*p2=*p2endl; temp=*p1; *p1=*p2; *p2=temp; cout调用中交换后:*p1=“ *p1,*p2=*p2endl; , cout调用中交换前:*p1=*p1,*p2=*p2endl; p=p1; p1=p2; p2=p; cout调用中交换后:*p1=*p1,*p2=*p2endl; ,int main( ) int x1,x2; cinx1x2; cout“1: x1=”x1“,x2=”x2endl; swap( ,方法 3,例6-3 编写函数实现两数的互换,10 1: x1=20,x2=10 调用中交换前:*p1=20,*p2=10 调用中交换后:*p1=10,*p2=20 2: x1=20,x2=10,2020/9/6,24/82,主调函数,被调函数,int main( ) int x1,x2; cinx1x2; cout1: x1=x1 ,x2=x2endl; swap( ,void swap(int *p1,int *p2) int *p; cout调用中交换前:*p1=“ *p1“,*p2=”*p2endl; p=p1; p1=p2; p2=p; cout调用中交换后:*p1=“ *p1,*p2=*p2endl; ,a0,a4,a,2020/9/6,26/82,用p表示数组元素 下标法: p0,p1, ,p9 指针法: *(p+0),*(p+1), ,*(p+9),2. 通过指针引用数组元素,例如:int a10,*p; p = a;(或 p = ),a,6.2.1 指针与一维数组,2020/9/6,27/82,【例6.4】用指针变量引用数组元素,完成给数组元素赋值并输出数组元素。 #include using namespace std; int main( ) int *p,b5,i; p=b; /* 建立指针和数组关联 */ for (i=0;i5;i+) *p+=i; p=b; /* 注意要把指针重新指向数组首地址 */ for (i=0;i5;i+) coutbi=*p+t; coutendl; return 0; ,6.2.1 指针与一维数组(续),运行结果 : b0=0 b1=1 b2=2 b3=3 b4=4,6.2.1 指针与一维数组,2020/9/6,28/82,3. 数组名与函数参数,【例6.5】从键盘输入5个整数,找出其中的最大数(用函数实现),并输出。,#include using namespace std; #define N 10 int my_max(int p, int n) /*形参为数组名*/ int i,max; max=p0; for(i=1; iai; max=my_max(a,N); /* 调用形参为数组名的max()函数*/ cout“Max:”maxendl; /* 输出结果 */ return 0; ,2020/9/6,29/82,6.2.1 指针与一维数组,2020/9/6,30/82,3. 数组名与函数参数,【例6.6】求已知数组中的最小值元素,并将它和该数组最前面的元素交换。,int min(int a , int n) /*定义求最小值元素下标值函数,形参a 为数组首指针 */ int i,m=0; for(i=1;iai) m=i; /* 记下比am小的元素下标 */ return (m); /* 返回最小值元素下标值*/ void swap(int *a, int m) /* 定义完成最小值元素与数组最前面的元素交换位置的函数,形参a为指针,准备接受数组首地址 */ int t; t=am; /* t暂存最小值元素值 */ am= a0; a0=t; /* 最小值元素放最前面 */ ,2020/9/6,31/82,#include using namespace std; #define N 10 int min(int a , int n); void swap(int *a, int m); int main( ) int i,aN,m; for(i=0; iai; m= min(a,N); /* 调用min( )函数,得到最小值元素下标 */ swap(a,m); /* 调用swap()函数,完成要求的交换 */ for(i=0;iN; i+) /* 输出交换后的数组元素值 */ coutai “ ”; coutendl; return 0; ,2020/9/6,32/82,运行情况如下: 55 5 12 4 1 45 8 89 62 54 1 5 12 4 55 45 8 89 62 54,6.2.1 指针与一维数组,2020/9/6,33/82,3. 数组名与函数参数,【例6.7】使用选择排序法对10个整数从大到小排序。,*(x+i)指向定位位置,*(x+k)指向当前最大值,*(x+j)将顺序指向参加比较的元素,最大值不在定位位置,#include using namespace std; void sort(int *x,int n) /* 定义选择排序法的函数 */ int i,j,k,t; for (i=0;in-1;i+) 10) /* 输出排序后的数组元素值 */ cout*p+ ; coutendl; return 0; ,2020/9/6,34/82,运行情况如下: 11 9 7 7 6 5 4 3 2 0,变量的地址和变量的内容 间接存取和直接存取 指针变量的定义 数据类型 * 指针变量名 指针变量的赋值 定义时:数据类型 * 指针变量名 = 二维数组名a是数组的首地址。 二维数组a包含三个行元素:a0、a1、a2 a0、a1、a2是一维数组名,也是一维数组的首地址。 a+0指向a0 a+1指向a1,a+2指向a2 所以:*(a+0)a0 、*(a+1)a1、*(a+2)a2 所以:*(a+0)、a0、*(a+1)、a1、*(a+2)、a2 都是列地址。,6.2.2 指针与二维数组,2020/9/6,39/58, 二维数组元素的地址,aij的地址可以用以下3种方式表示: int *p,i,j; p=a0; for (i=0;i3;i+) for(j=0;j4;j+) cout*(*(a+i)+j) “t“; /* 指针表示法输出元素aij */ coutendl; coutendl; for (i=0;i3;i+) for(j=0;j4;j+) cout*(ai+j) t; /* 行数组表示法输出元素aij */ coutendl; coutendl; (见下页),6.2.2 指针与二维数组,例6.8输出二维数组元素。,for (i=0;i3;i+) for(j=0;j4;j+) cout(*(a+i)j t; /* 列数组表示法输出元素aij */ coutendl; coutendl; for (i=0;i3;i+) for(j=0;j4;j+) cout*p+“t“; /* 指针直接表示法输出元素aij */ coutendl; return 0; ,运行情况如下(一共输出4个矩阵): 1 2 3 4 11 12 13 14 21 22 23 24 1 2 3 4 11 12 13 14 21 22 23 24 1 2 3 4 11 12 13 14 21 22 23 24 1 2 3 4 11 12 13 14 21 22 23 24,2020/9/6,42/58, 指向二维数组元素的指针变量,与指向一维数组元素的指针变量是相同的,用它存放二维数组元素的地址。,6.2.2 指针与二维数组,2020/9/6,43/58,6.2.3 指向字符串的指针变量,1. 用字符指针指向字符串,字符串的两种表示方式: 字符数组表示方式,字符串存放在一维数组中,引用时用数组名。 字符指针变量表示方式,字符指针变量存放字符串的首地址,引用时用指针变量名。,6.2.3 指向字符串的指针变量,对字符指针变量的赋值形式: 在定义字符指针时直接赋值,例如: char *cp=C Language; 在定义字符指针后赋值,例如: char *cp; cp= C Language; 将字符数组首地址赋值给字符指针,使该字符指针指向该字符串的首地址,例如: char str=C Language, *cp; cp=str;,2020/9/6,44/82,2020/9/6,45/58,int main( ) char s20; char *cp; int k; cp=s; /* cp指向s数组的首地址 */ couts; for(k=0;*(cp+k)!=0;k+) *(cp+k)+=3; /* 把ASCII码值加3*/ coutcpendl; return 0; ,【例6.9】简单的字符串加密就是将原字符所对应的ASCII码值加或减一个整数,形成一个新的字符。,6.2.3 指向字符串的指针变量,2020/9/6,46/82,2. 用字符串指针处理字符串,【例6.10】在输入的字符串中查找有无u字符。,#include using namespace std; int main( ) char *cp,ps20; coutps; /* 输入字符串 */ cp=ps; /* 循环前让cp指向字符串 */ while( *cp!=0) /* 当cp未移向串尾且未找到时继续循环查找 */ if (*cp=u) coutThe character u is cp-ps+1-thn; /* 位置从1算起 */ break; cp+; /* 顺序移动指针cp */ if (*cp=0) /* 循环结束后如未找到,此时cp应指向字符串尾标志0 */ coutThe character u is not found!n; return 0; ,6.2.3 指向字符串的指针变量,2020/9/6,47/82,2. 用字符串指针处理字符串,【例6.11】将字符串逆序排列后输出。,#include using namespace std; int main( ) char str80,*p,*q, t; coutstr; /* 输入要处理的字符串 */ for(p=str,q=p+strlen(str)-1;pq;p+,q-) /* 双向移动指针并交换相应元素 */ t=*p; *p=*q; *q=t; coutThe reversed string is: strendl; /* 输出逆序后的字符串 */ return 0; ,运行情况: Enter a string: language The reversed string is: egaugnal,6.2.3 指向字符串的指针变量,2020/9/6,48/82,3. 字符指针作为函数参数,【例6.12】形参用字符指针实现字符串间的拷贝。,#include using namespace std; void strcopy( char *s1, char *s2) ; int main( ) char *str1=C program, str220; strcopy(str1,str2); /* 分别以字符指针和字符数组名为实参 */ coutThe first stringis: str2endl; strcopy(FORTRAN language,str2); /* 分别以串常量为实参和数组名为实参 */ coutThe second string is : str2endl; return 0; void strcopy( char *s1, char *s2) /* 自定义求字符串拷贝函数strcopy() */ for(;*s1!=0;s1+,s2+)*s2=*s1; *s2=0; ,2020/9/6,49/82,指针数组定义的一般形式: 数据类型 *指针数组名元素个数; 在这个定义中由于“ ”比“*”的优先级高,所以数组名先与“元素个数”结合,形成数组的定义形式,“*”表示数组中每个元素是指针类型,“数据类型标识符”说明指针的目标变量的数据类型。例如: int *p3; char *cp5;,6.2.4 指针与数组,1. 指针数组的概念,指针数组就是数组中的每个元素均为 指针类型,2020/9/6,50/82,6.2.4 指针数组,2. 指针数组初始化,例如: char c8=Fortran,COBOL,BASIC,Pascal; char *cp4=c0,c1,c2,c3; int a, b, c, x23; int *ip3=,6.2.4 指针数组,#include using namespace std; int main( ) int a33=1,2,3,4,5,6,7,8,9,*pa3,i,j; for(i=0;i3;i+) pai=ai; /* 让指针数组元素分别指向三个一维数组 */ for(i=0;i3;i+) /* 按行输出二维数组元素 */ for(j=0;j3;j+) coutaij=*(pai+j) t; coutendl; return 0; ,2020/9/6,51/82,【例6.13】指针数组与二维数组之间的关系。,2020/9/6,52/82,3. 字符型指针数组和多个字符串的处理,6.2.4 指针数组,【例6.14】从键盘输入一个字符串,查找该字符串是否在已存在的字符串数组中。,int main( ) int i,flag; char *p5= C language,Basic,Pascal, Visual C+,FORTRAN; char str20; coutEnter a string:; /* 输入要查找的字符串 */ cin.getline(str,20); for(i=0;i5;i+) /* 逐个查找 */ if (strcmp(pi,str)=0) /* 若找到则令flag=-1,退出循环 */ flag=-1; break; if (flag=-1) /* 找到后flag应为-1*/ coutstr is founded.n; else coutstr is not founded.n; return 0; ,利用字符指针数组处理长度不等的字符串, 可节省存储空间。,2020/9/6,53/82,3. 字符指针数组和多个字符串的处理,6.2.4 指针数组,【例6.15】编写从多个字符串中找出最大字符串的函数。,char *maxstr(char *ps ,int n) /* 定义字符指针型函数maxstr( ),形参ps是字符型指针数组*/ char *max; int i; max=ps0; for(i=1;in;i+) /* 使max指向最大字符串 */ if (strcmp(max,psi)0) max=psi; return (max); /* 返回指针max值 */ int main( ) char *s5=PASCAL,FORTRAN,C program,Visual C+“, Visual Basic,*p; p=maxstr(s,5); /* 调用maxstr( ),得到最大字符串的指针 */ coutThe max string is : pn; /* 输出结果 */ return 0; ,2020/9/6,54/82,如果一个指针的目标变量是一个指针类型变量,则此指针为指向指针的指针变量,也称为多级指针变量。,二级指针变量定义的一般形式: 数据类型 *指针变量名; “数据类型”是最终目标变量的类型。例如: int a, *pa, *ppa;,6.2.5 多级指针,1. 二级指针变量定义形式,如果指针变量中保存的是另一个指针变量的地址,这样的指针变量就称为指向指针的指针 多级指针 实质就是多级间接寻址(Multiple Indirection),2020/9/6,55/82,6.2.5 多级指针,2. 二级指针变量初始化,例如: int a, *pa, *ppa; char *pname3, *ppname=pname;,、*pa,、*ppa,、*ppa,2020/9/6,56/82,6.2.5 多级指针,#include using namespace std; int main( ) float x=6.6; float *pp,*p; p= ,【例6.16】二级指针的应用。,运行情况如下: x=6.6=6.6=6.6,2020/9/6,57/82,6.3 指针和函数,6.3.1 指针型函数,1. 指针型函数定义形式,指针型函数定义的一般形式: 函数数据类型 *函数名(形式参数表) 其中函数名前的“*”表示函数的返回值是一个指针类型,“函数数据类型”是指针所指向的目标变量的类型。,如果一个函数的返回值是指针,则称此函数为指针型函数。,2020/9/6,58/82,6.3.1 指针型函数,【例6.17】运用指针型函数来找出两个数中的最大值。,int *max ( int *i , int *j ) /* 定义指针型函数,其形参为两个指针变量 */ if ( *i*j ) return ( i ); else return ( j ); int main( ) int a,b,*p; coutab; p=max ( ,2020/9/6,59/82,2. 指针型函数定义时应注意的问题, 指针函数中return的返回值必须是与函数类型一致的指针。 返回值必须是外部或静态存储类别的变量指针或数组指针,以保证主调函数能正确使用数据。,6.3.1 指针型函数,6.3.2 用函数指针调用函数,函数指针的定义形式: 数据类型 (* 函数指针变量名)(); 其中“*函数指针变量名”必须用圆括号括起来。在定义中“(*函数指针变量名)”右侧的括号“( )”表示指针变量所指向的目标是一个函数,不能省略;“数据类型”用于定义指针变量所指向的函数的类型。,2020/9/6,60/82,1. 函数指针的定义和赋值,6.3.2 用函数指针调用函数,说明: 通过改变指针变量的内容,一个指针变量可以先后指向同类型的不同函数,实现对不同函数的调用。 和数据指针一样,程序中不能使用指向不定的函数指针。 在给函数指针赋值时,只须给出函数名而不必给出参数,2020/9/6,61/82,1. 函数指针的定义和赋值,6.3.2 用函数指针调用函数,用函数指针变量调用函数的一般形式为: (*函数指针变量名)(实参表); 其中“*函数指针变量名”必须用圆括号括起来,表示间接调用指针变量所指向的函数;右侧括号中为传递到被调用函数的实参。,2020/9/6,62/82,2. 函数指针的使用,例如,若有函数int f1(int x,int y) 和int f2(char ch),则: int (*fs)( ); fs=f1; /* fs指向函数f1( ) */ x=(*fs)(a,b); /* 相当于x=f1(a,b); */ fs=f2; /* 改变fs内容,使fs指向函数f2( ) */ y=(*fs)(str); /* 相当于y=f2(str); */,6.3.2 用函数指针调用函数,运用函数指针变量调用函数时应注意的问题: 函数指针变量中应存有被调函数的首地址; 调用时“*函数指针变量名”必须用圆括号括起来,表示对函数指针做间接存取运算。它的作用等价于用函数名调用函数,此外实参表也应与函数的形参表一一对应。,2020/9/6,63/82,2. 函数指针的使用,6.3.2 用函数指针调用函数,2020/9/6,64/82,2. 函数指针的使用,【例6.18】用指向函数的指针调用函数以求二维数组中全部元素之和。,int main( ) int arr_add(int arr,int n); int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p,total1,total2; int (*pt)(int*,int); /*定义一个指向函数的指针*/ pt=arr_add; p=a0; total1=arr_add(p,12); /*用原函数名调用函数*/ total2=(*pt)(p,12); /*用指向函数的指针调用函数,将函数入口地址赋给指针*/ couttotal=total1endl; couttotal2=total2endl; return 0; ,arr_add(int arr ,int n ) int i,sum=0; for(i=0;in;i+) sum=sum+arri; return(sum); ,6.3.3 用指向函数的指针作函数参数,2020/9/6,65/82,【例6.19】写一程序,如输入1,程序就求数组元素的最大值,输入2就求数组元素的最小值,输入3就求数组元素值之和。,#define N 5 void process(int *x,int n,int (*fun)(int*,int ) /* 形参fun为函数指针 */ int result; result=(*fun)(x,n); /* 以函数指针fun实现 同类型相关函数的调用 */ coutresultendl; arr_max(int x ,int n) int max=x0,k; for(k=1;kn;k+) if (maxxk) max=xk; return (max); ,2020/9/6,66/82,arr_min(int x ,int n) int min=x0,k; for(k=1;kxk) min=xk; return (min); arr_sum(int x ,int n) int sum=0,k; for(k=0;kn;k+) sum+=xk; return (sum); ,2020/9/6,67/82,2020/9/6,68/82,6.3.4 带参数的main函数,1. 带参数的主函数的定义,main(int argc, char *argv ) ,main函数只能有两个形参,并且这两个形参的类型也是固定的。第一个形参必须是整型变量,第二个形参可以定义为字符型指针数组,也可以定义为二级字符指针变量,因此也可以写成 main(int argc, char *argv),2020/9/6,69/82,6.3.4 带参数的main函数,2. 带参数的主函数的调用,带参数的主函数调用形式: 可执行文件名 参数1 参数2 参数n 在DOS系统提示符下键入的这一行字符称为命令行。可执行文件名称为命令名,其后的参数称为命令行参数,命令名与各参数之间用空格进行分隔。,2020/9/6,70/82,3. 主函数参数的作用,argc 称作参数计数器,它的值是包括命令名在内的参数个数。 argv 指针数组的作用是存放命令行中命令名和每个参数字符串的首地址。 C:file1 one two three,6.3.4 带参数的main函数,2020/9/6,71/82,【例6.20】举例说明命令行参数与main()函数中两个参数之间的关系。,6.3.4 带参数的main数,int main(int argc, char *argv) if(argc=1) cout3) coutBad command!; return 0; ,2020/9/6,72/82,注意: 命令行参数所传送的数据全部都是字符串。即便传送的是数值,也是按字符串方式传送给主函数。程序中使用这些参数时,还需要将数字字符串转换成数值型数据。C语言标准库函数提供了一些相关的数据类型转换函数 。,6.4 动态存储分配,2020/9/6,73/82,6.4.1 什么是内存的动态分配,C+中允许建立内存动态分配区域,以存放一些临时用的数据。这些数据不必在程序的声明部分定义,也不必等到函数结束时才释放,而是在需要时随时开辟,不需要时随时释放。 这些数据临时存放在一个称为堆(heap)区的特别的自由存储区。可以根据需求,向系统申请所需大小的空间。由于未在声明部分将这些数据声明为变量,因此不能通过变量名引用这些数据,而只能通过指针来引用。 动态内存的生存期由程序员自己决定,使用非常灵活,但也最容易出现问题。使用过程中应牢记:“有借有还” 。,6.4.2 动态内存分配操作符,使用格式: new 数据类型 (表达式) 功能:分配若干字节的内存空间,返回一个指向该存储区地址的指针,指针的类型由“数据类型”确定。其中“表达式”用于对分配到的内存进行初始化。,2020/9/6,74/82,1. new操作符,例如: int *p1, *p2; p1=new int(5); /p1指向一整型空间,其中存有整数5 p2=new (int *); /p2指向一整型指针空间 *p2=new int (7); /*p2指向一整型空间,其中存有整数7,6.4.2 动态内存分配操作符,2. delete操作符,使用格式: delete 指针表达式, 指针表达式 功能:释放指针表达式指向的内存空间。,申请数组空间,new和delete的格式如下: new 数据类型行元素个数列元素个数 delete 指针表达式,指针表达式,6.4.2 动态内存分配操作符,注意,对于申请的数组空间,无法进行初始化。另外,第一维的维声明可以是在运行时求值的表达式,而从第二维开始就必须是在编译时即可求值的常量表达式。,例如: int *p1=new intn; /正确 int (*p2)6=new intm6; /正确 int (*p3)n=new intmn; /错误 int (*p4)n=new int10n; /错误,6.4.2 动态内存分配操作符,【例6-21】new和delete操作符的应用。,#include using namespace std; int main() int *p=new int8; /动态生成一数组空间,并用p指向它。 for (int i=0; i8; i+) pi=i+1; /用下标的方式给数组元素赋值 int *temp=p; for (int j=0;j8;j+) cout*temp+“ “; /用指针移动的方式输出数组元素的值 deletep; /释放new分配的一维数组 return 0; ,运行情况如下: 1 2 3 4 5 6 7 8,引用是变量的别名 引用通过运算符 int main() int intA=10,B=20; int 0,运行情况如下: 引用的值和相关变量值相同:refA=10 引用的变化,则相关变量也变化:intA=5 引用的地址和相关变量地址相同:intA的地址0 x0012FF7C 引用的地址和相关变量地址相同:refA的地址0 x0012FF7C,6.5.2 引用的操作,【例6-23】指针的引用,#include using namespace std; int main() int A=10, B=20; int *pti= ,运行情况如下: 指针的引用可以访问指针所指的变量:*ref=10 指针变量原来的值:pti=0012FF7C 引用的变化,则相关指针也变化:pti=0012FF78 指针所指的变量值也发生变化:*pti=20,6.5.3 不能被定义引用的情况,void类型不能定义引用。 数组名不能定义引用。 如: int arr10; int /错误!不能定义指向引用的指针 注意“int * char text1000; ; void slowfunc(bigone p1); /值传递函数 void fastfunc(bigone ,void slowfunc(bigone p1) /值传递函数 coutp1.serrnoendl; coutp1.textendl; void fastfunc(bigone ,运行情况如下: 123 This is a BIG structure 123 This is a BIG structure,6.5.5 用引用返回多个值,【例6-25】Factor()函数检查用值传递的第一参数。如果不在-的范围内,它就简单地返回错误值(假设程序正常返回为)。程序所真正需要的值squared和cubed是通过改变传递给函数的引用返回的,而没有使用函数返回机制。,#include using namespace std; int Factor(int, int ,int Factor(int n, int ,运行情况如下: Enter a number(0-20):13 Number:13 Squared:169 Cubed:2197,STOP,6.5.6 函数返回值类型为引用,函数返回值类型为引用,其格式如下: int ,6.5.6 函数返回值类型为引用,【例6-26】函数返回值类型为引用。,运行情况如下: sum=15,6.5.7 const引用,使用const修饰符修饰引用,即为常引用。该引用所引用的对象不能被更新。其定义格式如下: const 其中,n、vst是常引用,其所引用的对象不会被更新。,#include using namespace std; void display(const double ,6.5.7 const引用,【例6-27】分析以下程序的执行结果。,运行情况如下: 6.3,#include using namespace std; struct Date int month,day,year; ; Date birthdays=12,17,37,10,31,38,6,24,40, 11,23,42,8,5,44; const Date ,6.5.7 const引用,【例6-28】const引用应用举例。,int main() int dt=99; while(dt!=0) cout dt; if (dt0 ,运行情况如下: Enter date # (1-5, 0 to quit):1 12/17/37 Enter date # (1-5, 0 to quit):2 10/31/38 Enter date # (1-5, 0 to quit):3 6/24/40 Enter date # (1-5, 0 to quit):4 11/23/42 Enter date # (1-5, 0 to quit):5 8/5/44 Enter date # (1-5, 0 to quit):0,作业: 填空 5,6,7,10 编程 3,4,
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!