版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1第第5章章 指针指针 皮德常皮德常南京航空航天大学南京航空航天大学 计算机科学与技术学院计算机科学与技术学院25.1 指针的概念指针的概念 例如,假设定义有如下例如,假设定义有如下2个变量:个变量:int num=123;char ch=A; 35.2 指针变量指针变量 存放指针或者说地址的变量就是指针变量。存放指针或者说地址的变量就是指针变量。 一般变量的内存单元中存放的是数据,指针变量一般变量的内存单元中存放的是数据,指针变量的内存单元中存放的是地址。的内存单元中存放的是地址。45.2.1 定义指针变量定义指针变量 例如:例如:int*pInt ; char*pChar ; 1:指针不指
2、向内存的:指针不指向内存的0号单元。如果指针变量值为号单元。如果指针变量值为0(即(即NULL ),表示空指针。,表示空指针。2. 地址值与整型数值不同。如地址地址值与整型数值不同。如地址1000与整数与整数1000。3. 无论是何种类型的指针都占无论是何种类型的指针都占4个字节的内存空间。个字节的内存空间。例如:例如:int *pInt ;char *pChar ;double *pDouble ;float *pFloat ;cout sizeof( pInt) t sizeof( pChar) t sizeof( pDouble) t sizeof( pFloat) endl; Ex5-
3、a.cpp65.2.2 运算符运算符 & 和和 * &:取内存变量地址,例如:取内存变量地址,例如:char *pChar, ch=A;pChar = &ch ; 75.2.2 运算符运算符 & 和和 * 2. *:通过指针间接访问所指变量:通过指针间接访问所指变量 char *pChar, ch1=A, ch2 ;pChar = &ch1;ch2 = *pChar; *pChar = B ; 指针变量初始化:指针变量初始化:char ch=A, *pChar = &ch, *p = NULL ; 85.2.2 运算符运算符 & 和和 *
4、 思考思考: *符号的含义:符号的含义:1. int num=16,*pInt=# *pInt =123; 3. num *= 123; 95.2.3 引用指针变量引用指针变量 例如:例如:1 intx = 30 , y = 90; 2 int*p1=&x , *p2 = &y, *t ;3 t = p1; p1 = p2;p2 = t;思考:思考:*p1、 *p2、x 和和 y的值?如下形式又是多少?的值?如下形式又是多少?1intx = 30 , y = 90; 2int*p1 = &x , *p2 = &y, t ;3t = *p1; *p
5、1 = *p2;*p2 = t; 105.3 指针与数组指针与数组 访问数组的方式:下标形式、指针形式。访问数组的方式:下标形式、指针形式。 数组要么在静态存储区中被创建,如全局数组和静态数数组要么在静态存储区中被创建,如全局数组和静态数组;要么在栈上被创建,如一般的局部数组。组;要么在栈上被创建,如一般的局部数组。 数组名对应着一块内存,其地址与容量在其生命期内保数组名对应着一块内存,其地址与容量在其生命期内保持不变,只有数组的内容可以改变。持不变,只有数组的内容可以改变。 指针可以指向任意类型的内存块,它的特征是指针可以指向任意类型的内存块,它的特征是“可变可变”。指针比数组灵活,但也更容
6、易出错。指针比数组灵活,但也更容易出错。 115.3.1 指向数组元素的指针指向数组元素的指针 数组名代表该数组的开始地址,这意味着数组名是数组名代表该数组的开始地址,这意味着数组名是一个指针常量,例如:一个指针常量,例如: int a10;int a10, *p;p = &a0; 则则 p、 a 、 &a0是一个值。是一个值。125.3.1 指向数组元素的指针指向数组元素的指针 思考:思考:下面的程序涉及指针与数组,有什么错?下面的程序涉及指针与数组,有什么错? char str = hello; str0 = X; cout str endl; char *p = worl
7、d; p0 = X; / 编译器查不出该错误编译器查不出该错误 cout p endl; Ex5-b.cpp135.3.2 指针的运算指针的运算 1指针指针 整数值整数值 例:例:int a10, *p1, *p2;p1 = &a2; p2 = p1 + 3; 注意如下形式,易错:注意如下形式,易错:int m = *p1+ , n = *+p2; 【例例5.1】通过指针使一个数组逆序存放。通过指针使一个数组逆序存放。 int set = 10, 20, 30, 40, 50, 60, 70, 80;int *p1,*p2, t, i, length ;length = sizeof(
8、set) / sizeof(set0);p1 = set;p2= set + length -1;for( i = 0; i length / 2; i+)t=*p1;*p1=*p2;*p2=t;p1+;-p2;for( i = 0; i length; i+)cout seti t;5-1.cpp思考:思考:如下程序段的输出结果:如下程序段的输出结果:int set = 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, *p = &set3;cout p0 set0 *( p+3) *(set+3) ; 165.3.2 指针的运算指针的运算 2指针相减
9、,指针相减,例如:例如: int *p1 ,*p2 , n , a =2, 4, 6, 8, 10; p1 = &a1; p2 = &a4; n = p2 p1 ; n = p1 p2 ; 注意:若有指针注意:若有指针p3,让其指向数组中间的一个元素:,让其指向数组中间的一个元素:p3 = p1 + ( p2 p1 ) / 2 。 175.3.2 指针的运算指针的运算 3指针比较:指向同一个数组的两个指针可进行的比指针比较:指向同一个数组的两个指针可进行的比较包括较包括 =、!=、和和=修改修改【例例5.1】int set = 10, 20, 30, 40, 50, 60, 7
10、0, 80;int *p1,*p2, t, i, length ;length = sizeof(set) / sizeof(set0);for( p1 = set, p2 = set + length -1; p1 p2 ; p1+, p2- )t=*p1; *p1=*p2; *p2=t; 185.3.3 二维数组与指针二维数组与指针 1. 对数组的理解。对数组的理解。 行指针:如行指针:如a和和a+1 元素指针:如元素指针:如 *a 和和 *(a+1) 195.3.3 二维数组与指针二维数组与指针 2二维数组元素二维数组元素aij的表示的表示 (1) aij的地址可表示为:的地址可表示为:
11、&aij、ai+j和和 *(a+i)+j 。(2) 元素表示为:元素表示为:aij、*(ai+j)、*(*(a+i)+j) 和和 (*(a+i)j 例如:输出一个例如:输出一个23二维数组的每个元素地址和元素值:二维数组的每个元素地址和元素值:int a23=10, 20, 30, 40, 50, 60, *p ;for( p = a0; p a0 + 6; p+ ) cout setw(5) p setw(5) *p endl; Ex5-c.cpp205.3.3 二维数组与指针二维数组与指针 3行指针变量行指针变量 一维数组:一维数组: int b10, *pb = b ;pb与与b
12、、*pb与与*b、pb+1与与b+1、*( pb+1)与与*(b+1)分别等价。分别等价。 二维数组与行指针变量:二维数组与行指针变量: int a34,(*pa)4 = a; (1) pa与与a都是都是a0大元素的地址;大元素的地址; (2) *pa与与*a都是都是a0,是,是a00元素的地址;元素的地址;(3) pa+1与与a+1都是都是a1大元素的地址;大元素的地址;(4) *( pa+1)与与*(a+1) 都是都是a1,是,是a10元素的地址。元素的地址。 21【例例5.2】输出二维数组的地址。输出二维数组的地址。int a34=1,2,3,4,5,6,7,8,9,10,11,12 ;
13、cout ata0t *(a+0 )t&aendl;cout a+1ta1t *(a+1)t&a1endl;cout a1+2t*(a+1)+2t &a12tendl;5.3.3 二维数组与指针二维数组与指针 5-2.cpp22【例例5.3】通过行指针变量访问二维数组元素。通过行指针变量访问二维数组元素。 int a33, (*p)3;int sum=0, i, j;srand(time(0 );p=a;for(i=0; i3; i+)for(j=0; j3; j+) *( pi+j)= rand( )%20; cout setw(5) pij;cout endl;fo
14、r(i=0; i3; i+) sum += *(*( p+i)+i) + *(*( p+i)+(2-i) ; 5.3.3 二维数组与指针二维数组与指针 5-3.cpp23【例例5.4】编写一个通用的二维数组输出函数。编写一个通用的二维数组输出函数。 void print ( int *p, int row, int col) int i; for( i=0; irow*col; i+, p+) if( i%col = 0 ) cout endl; cout setw(4) *p; cout endl; 5.3.3 二维数组与指针二维数组与指针 5-4.cpp245.4 指针与函数指针与函数 C
15、+中的函数参数的传递方式:中的函数参数的传递方式:(1)传值调用;传值调用;(2) 传引用。传引用。 另一种在函数中可以修改相应实参的方法,是通另一种在函数中可以修改相应实参的方法,是通过指针传递(实际上是传递指针的值,属于传值过指针传递(实际上是传递指针的值,属于传值调用)。调用)。 25【5.4】交换变量交换变量x与与y的值。采用基本类型的变量做函数形参。的值。采用基本类型的变量做函数形参。5.4 指针与函数指针与函数 void main ( )int x=10, y=20;swap(x, y);cout x t y endl;void swap( int a, int b)int t;t
16、 = a ; a = b ; b = t ; Ex5-d.cpp26【5.5】交换变量交换变量x与与y的值。采用引用做函数形参。的值。采用引用做函数形参。 int main ( )int x=10, y=20;swap(x, y);cout x t y endl;return 0;void swap(int &a, int &b)int t;t = a ; a = b ; b = t ; 5.4 指针与函数指针与函数 Ex5-e.cpp27【5.6】交换变量交换变量x与与y的值。采用指针做函数形参。的值。采用指针做函数形参。 int main ( )int x=10, y=20
17、;swap( &x, & y);cout x t y endl;return 0;void swap(int *px, int *py )int t;t=*px ; *px=*py ; *py= t; 5.4 指针与函数指针与函数 Ex5-f.cpp【例例5.6】将数组中从第将数组中从第i个开始的个开始的n个元素,反序存放在原数组中。个元素,反序存放在原数组中。 void reverseArray(int x ,int start, int count); int main ( ) int i,a10=0,1,2,3,4,5,6,7,8,9;reverseArray(a,2,6
18、);for(i=0;i10;i+)cout setw(5) ai ;return 0; void reverseArray( int x ,int start, int count)int t, i, j;for(i=start,j=start+count-1; ij; i+,j-)t=xi; xi=xj; xj=t; 5-6.cpp思考下面的问题输出结果:思考下面的问题输出结果:char str = hello world;char *ps = str;cout sizeof(str) endl;cout sizeof( ps) endl;void fun(char str100)cout
19、sizeof(str) m ; p = search( score,m); for(i=0;i4;i+) cout setw(5) *( p+i);5-7.cpp31函数可返回一个指针,但必须保证指针指向的对象存在。函数可返回一个指针,但必须保证指针指向的对象存在。分析如下函数存在的错误:分析如下函数存在的错误: char *getName( )char name81;cout y ? x: y; funP=max ; 调用函数调用函数max的方法:的方法: k = max(10,20 ); k = (*funP)(10,20 ); k = funP(10,20 ); 33指向函数的指针指向函
20、数的指针 【5.8】采用函数名做参数。采用函数名做参数。 int max(int, int) ;int min(int, int) ;int add(int, int) ;int process(int x, int y, int (*fun)(int, int) return fun(x, y) ; void main ( )int a, b ;cin a b ;cout process(a, b, max) endl ; cout process(a, b, min) endl ;cout process(a, b, add) endl ;5-8.cpp345.5 指针数组与指向指针的指针
21、指针数组与指向指针的指针 5.5.1 指针数组指针数组 例如:例如:int *pInt5; 思考如下程序片段的含义:思考如下程序片段的含义:int a6, *p3, i;for(i=0; i 6; +i) ai = i*3;for(i=0; i 3; +i)pi=&ai*2;for(i=0; i 3; +i)cout setw(5) *( pi+1);自学自学【例例5.10】。 355.5.2 main 函数的参数函数的参数 在在main( )函数头部声明的格式为:函数头部声明的格式为: int main( int argc, char *argv ) int main (int ar
22、gc, char *argv) argc表示命令行中字符串的个数。表示命令行中字符串的个数。argv 指向命令行中的各个字符串。指向命令行中的各个字符串。36【例例5.11】通过命令行参数计算输入数据的和。通过命令行参数计算输入数据的和。void main (int argc, char *argv ) int sum, i; cout Command name: argv0 endl; for(sum=0, i=1; iargc; i+) sum += atoi(argvi);cout Sum is: sum endl; 5-11.cpp37思考如下程序段的输出结果:思考如下程序段的输出结果
23、:void main (int argc, char *argv ) cout + * + * + argv endl;cout + * + * argv endl; Ex5-i.cpp385.5.3 指向指针的指针指向指针的指针 例如:例如:int x=89,*p = &x , *pp; p = &x ;pp = &p ; void main( ) int a =10, 20, 30, 40, 50; int *p =a, a+1, a+2, a+3, a+4; int *pp=p; cout setw(5) *p4;cout setw(5) *( p+1);cout
24、 setw(5) *pp+;cout setw(5) *+pp;cout setw(5) *+*pp endl; 分析该程序分析该程序的输出结果的输出结果Ex5-j.cpp395.6 内存的动态分配和释放内存的动态分配和释放 分配单个元素空间:分配单个元素空间:int *iptr ;iptr = new int ;*iptr = 25 ;iptr = new int(30 ) ;cout *iptr;total += *iptr ;delete iptr ;分配一片空间:分配一片空间:int *a ;a = new int 100 ;if ( NULL = a ) cout 分配空间失败分配空
25、间失败 ! n” ; exit ( 0 ) ; delete a ;405.6 内存的动态分配和释放内存的动态分配和释放 如果函数的参数是一个指针,不要用该指针去申请动态内存,如果函数的参数是一个指针,不要用该指针去申请动态内存,例如:例如:void getMemory(char *p, int num) p = new charnum;void test( ) char *str = NULL; getMemory(str, 100 ); strcpy(str, hello); Ex5-k.cpp【例例5.12】new和和delete操作符的应用。要求用户输入每天的操作符的应用。要求用户输入
26、每天的销售量,并把这些数据存储在动态分配的数组中,然后计算销售量,并把这些数据存储在动态分配的数组中,然后计算它们的总和与平均值。它们的总和与平均值。 int main ( ) float *sales, total = 0, average ; int numDays , count ; cout numDays ; sales = new float numDays ; if ( NULL = sales ) cout 分配内存空间失败分配内存空间失败 !n ; exit ( 0 ) ; 5-12.cpp cout 请输入如下的销售量请输入如下的销售量n ; for ( count = 0
27、 ; count numDays ; count+ ) cout 第第 (count + 1) sales count ; for ( count = 0 ; count numDays ; count+ ) total += sales count ; average = total / numDays ; cout.precision ( 2 ) ; cout.setf ( ios:fixed | ios:showpoint ) ; cout n总的销售量总的销售量: total endl ; cout 平均销售量平均销售量: average endl ; delete sales ; r
28、eturn 0; 435.7 void和和const修饰指针变量修饰指针变量 5.7.1 void修饰指针修饰指针 void修饰指针代表是一种不确定类型的指针。修饰指针代表是一种不确定类型的指针。 1. 任何类型的指针都可以直接赋给它,无需类型转换:任何类型的指针都可以直接赋给它,无需类型转换: void *p1;int *p2; p1 = p2;2. 不能对不能对void指针进行算术操作:指针进行算术操作: void * p; p+; p += 1; 【例例5.13】交换两个数的通用程序,可交换整数、字符或同交换两个数的通用程序,可交换整数、字符或同等类型且个数相等的数组。等类型且个数相等的
29、数组。 void swap(void *p1, void *p2, int elemNumber);int main ( ) double x=99.9, y=88.8;swap( &x, &y, sizeof(double) );cout交换后交换后:x=x y=yendl;int a =1,2,3,4,5, b =31,32,33,34,35;swap( a, b, sizeof(a);for(i=0;isizeof(a)/sizeof(*a); i+)cout setw(5)ai;coutendl b=;for(i=0;isizeof(b)/sizeof(*b); i+)
30、cout setw(5)bi;coutendl;5-13.cppvoid swap( void *p1, void *p2, int elemNumber)char *first=(char *)p1, *second=(char *)p2, temp;for(int k=0;kelemNumber;k+) temp=firstk;firstk=secondk;secondk=temp;465.7.2 const修饰指针修饰指针 1由由const定义的指针常量,可以改变指针所指定义的指针常量,可以改变指针所指的空间,但不可以通过指针改变现在所指的内容,的空间,但不可以通过指针改变现在所指的内容
31、,例如:例如: int i=6; const int *p1=&i; const int m=30; const int *p2=&m; *p1=16;/错误错误 p1=&m;/正确正确475.7.2 const修饰指针修饰指针 2通过通过const定义常量指针,通过这种变量,可定义常量指针,通过这种变量,可以改变指针所指向空间中的内容,但不能改变指以改变指针所指向空间中的内容,但不能改变指针的指向,例如:针的指向,例如: char stringA10=abcd, stringB10=xyz; char *const sp=stringA; sp = stringB;/
32、错误错误 *(sp+1)=t; coutstringA=spendl;485.7.2 const修饰指针修饰指针 3指向指向const变量的指针变量,不可以通过这种变量的指针变量,不可以通过这种指针变量修改所指的内容,也不可以改变指针的指针变量修改所指的内容,也不可以改变指针的指向,例如:指向,例如:int i=100, j=200;const int * const p=&i; i=20;/ 正确正确*p=0;/ 错误错误 p=&j;/ 错误错误495.8 对容易混淆概念的总结对容易混淆概念的总结 1. int *p; p是一个指向整型量的一般指针。是一个指向整型量的一般指针
33、。int i, a10, b34, *p;p=&i; / p指向简单整型变量指向简单整型变量 p=&a3; / p指向一个元素指向一个元素 p=&b23; / p指向一个元素指向一个元素 p=a;p+; / 正确正确 a+; / 错误错误 +*p / 将将p指向的变量值加指向的变量值加1 505.8 对容易混淆概念的总结对容易混淆概念的总结 2. int (*p)M; / p是一个行指针。是一个行指针。int a34, (*p)4;p=a;p+; / p指向数组指向数组a的下一行的下一行3. int * pM; / 由指针构成的数组,指针数组,由指针构成的数组,指针数组,4. int *p; / 指向整型指针的指针。指
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GB/T 48265-2026数据要素标识规范
- 2026司法入学面试题目及答案
- 2026思维判断面试题及答案
- 2026思政助理面试题及答案
- 2026四川水务面试题目及答案
- 彩色折纸课件
- 慈善主题演讲课件
- 参赛作品介绍课件
- 城市因我而美丽课件
- 2026 四川事业编社会工作岗 结构化面试 含答案
- 长征胜利 90 周年 长征精神与新时代青年责任担当课件
- 2026 版特殊作业监护人员安全手册
- 麻醉科麻醉复苏查房课件
- 2026年西藏自治区中考化学试题(含解析)
- 日本漫画介绍课件教学
- 2025-2026学年浙江省初中名校共同体七年级(上)期中语文试卷(含答案)
- 雨课堂学堂云在线《篮球-基本技术》单元测试考核答案
- 知到《美丽中国(双语)(山东建筑大学)》智慧树网课完整版章节测试答案
- 快递行业交通安全培训课件
- DB51∕T 3243-2024 四川省生态系统生产总值(GEP)核算技术规范
- 非妇科液基细胞学制片技术
评论
0/150
提交评论