
善于使用指针.ppt
54页8.1 什么是指针什么是指针8.2 指针变量指针变量8.3 通过指针引用数组通过指针引用数组8.4 通过指针引用字符串通过指针引用字符串8.5 提高部分提高部分第第8章章 善于使用指针善于使用指针P2108.1 8.1 什么是指针什么是指针什么是指针什么是指针Ø在定义变量时,系统就给这个变量分配在定义变量时,系统就给这个变量分配内存单元内存单元Ø编译系统根据程序中定义的变量类型,编译系统根据程序中定义的变量类型,分配一定长度的空间分配一定长度的空间P2108.1 8.1 什么是指针什么是指针什么是指针什么是指针Ø内存区的每一个字节有一个编号,这就内存区的每一个字节有一个编号,这就是内存单元的是内存单元的“地址地址”Ø在地址所标志的内存单元中存放数据在地址所标志的内存单元中存放数据P210Ø由于通过地址能找到所需的变量单元,由于通过地址能找到所需的变量单元,我们可以说,地址指向该变量单元我们可以说,地址指向该变量单元Ø在在C语言中,将地址形象化地称为语言中,将地址形象化地称为“指指针针”意思是通过它能找到以它为地址意思是通过它能找到以它为地址的内存单元的内存单元8.1 8.1 什么是指针什么是指针什么是指针什么是指针P210int a,b;ab2000 2004a=3;3直接访问直接访问8.1 8.1 什么是指针什么是指针什么是指针什么是指针P210int a;3aa_pointer2000a_pointer=&a;间接访问间接访问定义特殊变量定义特殊变量a_pointer2000通过通过a_pointer取值取值8.1 8.1 什么是指针什么是指针什么是指针什么是指针P210Ø为了表示将数值3送到变量中,可以有两为了表示将数值3送到变量中,可以有两种表达方法:种表达方法:(1) 将将3直接送到变量直接送到变量a所所代表代表的单元中的单元中(2) 将将3送到变量送到变量a_pointer所指向的单元所指向的单元(即(即a所代表所代表的存储单元)的存储单元)Ø指向就是通过地址来体现的指向就是通过地址来体现的u假设假设a_pointer中的值是变量中的值是变量a的地址的地址(2000),这样就在,这样就在a_pointer和变量和变量a之间之间建立起一种联系,即通过建立起一种联系,即通过a_pointer能知道能知道a的地址,从而找到变量的地址,从而找到变量a的内存单元的内存单元Ø一个变量的一个变量的地址地址称为该变量的称为该变量的“指针指针”例如,地址例如,地址2000是变量是变量i的指针的指针Ø如果有一个变量专门用来存放另一变量的如果有一个变量专门用来存放另一变量的地址(即指针),则它称为地址(即指针),则它称为“指针变量指针变量”Øa_pointer就是一个指针变量。
指针变量就是一个指针变量指针变量就是地址变量,用来存放地址的变量,指就是地址变量,用来存放地址的变量,指针针变量的值是地址(即指针)变量的值是地址(即指针)Ø“指针指针”和和“指针变量指针变量”是是不同的不同的概念概念Ø可以说变量可以说变量a的指针是的指针是2000,而不能说,而不能说a的指针变量是的指针变量是2000Ø指针是一个地址,而指针变量是存放地址指针是一个地址,而指针变量是存放地址的变量的变量Ø常常将指针变量简称为指针常常将指针变量简称为指针8.28.2 指针变量指针变量指针变量指针变量8.2.1 使用指针变量访问变量的例子使用指针变量访问变量的例子8.2.2 怎样定义指针变量怎样定义指针变量8.2.3 怎样引用指针变量怎样引用指针变量8.2.4 指针变量作为函数参数指针变量作为函数参数P2118.2.1 8.2.1 使用指针变量访问变量的例子使用指针变量访问变量的例子使用指针变量访问变量的例子使用指针变量访问变量的例子例例8.1 通过指针变量访问整型变量通过指针变量访问整型变量P2118.2.2 8.2.2 怎样定义指针变量怎样定义指针变量怎样定义指针变量怎样定义指针变量P212Ø定义指针变量的一般形式为:定义指针变量的一般形式为: 类型类型 * 指针变量名指针变量名;如:如:int *p1, *p2;uint是是为为指针变量指定的指针变量指定的“基类型基类型”u基类型指定指针变量可指向的变量类型基类型指定指针变量可指向的变量类型u如如pointer_1可以指向整型变量,但不能指可以指向整型变量,但不能指向浮点型变量向浮点型变量8.2.2 8.2.2 怎样定义指针变量怎样定义指针变量怎样定义指针变量怎样定义指针变量P212Ø下面都是合法的定义下面都是合法的定义和初始化和初始化::float *pointer_3;char *pointer_4;int a,b;int *pointer_1=&a,*pointer_2=&b;8.2.3 8.2.3 怎样引用指针变量怎样引用指针变量怎样引用指针变量怎样引用指针变量P214Ø在引用指针变量时,可能有三种情况:在引用指针变量时,可能有三种情况:u给指针变量赋值。
如:给指针变量赋值如:p=&a;u引用指针变量指向的变量引用指针变量指向的变量如如有有 p=&a; *p=1; 则执行则执行printf(“%d”,*p); 将输出将输出1u引用指针变量的值如:引用指针变量的值如:printf(“%p”,p);使使p指向指向a*p相当于相当于a以以十六十六进制输出进制输出a的地址的地址8.2.3 8.2.3 怎样引用指针变量怎样引用指针变量怎样引用指针变量怎样引用指针变量P214Ø要熟练掌握两个有关的运算符:要熟练掌握两个有关的运算符:(1) && 取地址运算符取地址运算符 &a是变量是变量a的地址的地址(2) * 指针运算符(指针运算符(“间接访问间接访问”运算符)运算符) 如果如果:: p指向变量指向变量a,,则则*p就代表就代表a k=*p; (把把a的值的值赋给赋给k) *p=1; (把把1赋给赋给a)8.2.4 8.2.4 指针变量作为函数参数指针变量作为函数参数指针变量作为函数参数指针变量作为函数参数P215 例例8.3 利用函数交换两个整数的值利用函数交换两个整数的值。
8.38.3 通过指针引用数组通过指针引用数组通过指针引用数组通过指针引用数组P2208.3.1 数组元素的指针数组元素的指针8.3.2 通过指针引用数组元素通过指针引用数组元素8.3.3 用数组名作函数参数用数组名作函数参数8.3.1 8.3.1 数组元素的指针数组元素的指针数组元素的指针数组元素的指针P220Ø一个变量有地址,一个数组包含若干元素,一个变量有地址,一个数组包含若干元素,每个数组元素都有相应的地址每个数组元素都有相应的地址Ø指针变量可以指向数组元素(把某一元素指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中)的地址放到一个指针变量中)Ø所谓数组元素的指针就是数组元素的地址所谓数组元素的指针就是数组元素的地址Ø可以用一个指针变量指向一个数组元素可以用一个指针变量指向一个数组元素 int a[10]={1,3,5,7,9,11,13,15,17,19}; int *p; p=&a[0];等价于等价于p=a;等价于等价于int *p=a;或或int *p=&a[0];注意注意:数组名数组名a不代表整个数组,不代表整个数组,只代表数组首元素的地址。
只代表数组首元素的地址p=a;”的作用是的作用是“把把a数组的首数组的首元素的地址赋给指针变量元素的地址赋给指针变量p”,而不,而不是是“把数组把数组a各元素的值赋给各元素的值赋给p”8.3.2 8.3.2 通过指针引用数组元素通过指针引用数组元素通过指针引用数组元素通过指针引用数组元素Ø引用数组元素,可用下面两种方法:引用数组元素,可用下面两种方法: ((1)下标法,用数组名加下标)下标法,用数组名加下标 如如a[i] ((2)指针法,即地址法指针法,即地址法 *(a+i) 或或*(p+i) (其中(其中初值初值p=a))P221Ø指针运算:通过指针的运算,可以方便地指针运算:通过指针的运算,可以方便地引用数组中的元素引用数组中的元素1) 如果指针变量如果指针变量p已指向数组中的一个元已指向数组中的一个元素,则素,则p+1指向同一数组中的下一个元素,指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素指向同一数组中的上一个元素 float a[10],*p=a; 假设假设a[0]的地址为的地址为2000,则,则up的值为的值为2000up+1的值为的值为2004(2) 如果如果p的初的初值为值为&a[0],,则则p+i和和a+i就就是数组元素是数组元素a[i]的地址,的地址,或者说,它们或者说,它们指向指向a数组序号数组序号为为i的元素的元素a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]pp+1,a+1 p+i,a+i p+9,a+9 (3) *(p+i)或或*(a+i)是是p+i或或a+i所指向的所指向的数组元素,即数组元素,即a[i]。
a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]pp+1,a+1 p+i,a+i p+9,a+9 *(p+i)(4) 如果指针如果指针p1和和p2都指向同一数组都指向同一数组 p2-p1的值的值是是4 不能不能p1+p2a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]p1p2 8.3.3 8.3.3 用数组名作函数参数用数组名作函数参数用数组名作函数参数用数组名作函数参数P224Ø用数组名作函数参数用数组名作函数参数时,因为时,因为实参数组名实参数组名代表该数组首元素的地址代表该数组首元素的地址,,形参应该是一形参应该是一个指针变量个指针变量ØC编译都是将形参数组名作为指针变量来编译都是将形参数组名作为指针变量来处理的处理的void fun(int arr[ ],int n) { ┇ ┇ }void main() { void fun(int arr[],int n]; int array[10]; ┇ ┇ fun (array,10); } fun(int *arr,int n)void fun(int arr[ ],int n) { ┇ ┇ }void main() { void fun(int arr[],int n]; int array[10]; ┇ ┇ fun (array,10); } array[0]arr[0]array数组数组arrarray[3]arr[3]arr+3Ø 实参数组名是指针常量,但形参数组名是实参数组名是指针常量,但形参数组名是按指针变量处理按指针变量处理Ø在函数调用进行虚实结合后,它的值就是在函数调用进行虚实结合后,它的值就是实参数组首元素的地址实参数组首元素的地址Ø在函数执行期间,在函数执行期间,形参数组形参数组可以再被赋值可以再被赋值void fun (arr[ ],int n){ printf(″%d\n″, *arr); arr=arr+3; printf(″%d\n″, *arr); }8.4 8.4 通过指针引用字符串通过指针引用字符串通过指针引用字符串通过指针引用字符串8.4.1 字符串的表示形式字符串的表示形式8.4.2 字符指针作函数参数字符指针作函数参数8.4.3 对使用字符指针变量和字符对使用字符指针变量和字符数组的讨论数组的讨论P2298.4.1 8.4.1 字符串的表示形式字符串的表示形式字符串的表示形式字符串的表示形式Ø可以用两种方法访问一个字符串可以用两种方法访问一个字符串::(1) 用字符数组存放一个字符串,然后用字用字符数组存放一个字符串,然后用字符数组名和下标可以访问字符数组中的元素,符数组名和下标可以访问字符数组中的元素,也可以通过字符数组名用也可以通过字符数组名用%s格式符输出一格式符输出一个字符串。
个字符串2) 用字符指针指向一个字符串可以不定用字符指针指向一个字符串可以不定义字符数组,而定义一个字符指针用字符义字符数组,而定义一个字符指针用字符指针指向字符串中的字符指针指向字符串中的字符P229 例例8.10 定义字符指针,使它指向一个定义字符指针,使它指向一个字符串 #include
也可以指向多维数组中的元素 P240int a[3][4]={{1,3,5,7}, {9,11,13,15},{17,19,21,23}};1357911131517192123a[0]a[1]a[2]aa+1a+2int (*p)[4];指向一维数组的指针变量指向一维数组的指针变量p=a+1;p指向指向a[1]行行的开头的开头8.5.3 8.5.3 指向函数的指针指向函数的指针指向函数的指针指向函数的指针Ø如果在程序中定义了一个函数,在编译如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址空间,这段存储空间的起始地址,,称为称为这个函数的指针这个函数的指针P2418.5.3 8.5.3 指向函数的指针指向函数的指针指向函数的指针指向函数的指针Ø可以定义一个指向函数的指针变量,用来可以定义一个指向函数的指针变量,用来存放某一函数的起始地址,这就意味着此存放某一函数的起始地址,这就意味着此指针变量指向该函数例如:指针变量指向该函数例如: int (*p)(int,int); 定义定义p是指向函数的指针变量,它可以指是指向函数的指针变量,它可以指向向的函数的函数类型为整型且有两个整型类型为整型且有两个整型形形参参 P2418.5.3 8.5.3 指向函数的指针指向函数的指针指向函数的指针指向函数的指针Ø定义的一般形式为:定义的一般形式为:数据类型数据类型 (*指针变量名指针变量名)(函数参数表列函数参数表列);Ø如果要用指针调用函数,必须先使指针变如果要用指针调用函数,必须先使指针变量指向该函数。
如:量指向该函数如:p=max; 把把max函数的入口地址赋给指针变量函数的入口地址赋给指针变量p P2418.5.3 8.5.3 指向函数的指针指向函数的指针指向函数的指针指向函数的指针Ø调用函数时,只需将调用函数时,只需将(*p)代替函数名即可代替函数名即可例如:例如:c=(*p)(a,b); 相当于:相当于:c=max(a,b);Ø指向函数的指针变量的一个重要用途是把指向函数的指针变量的一个重要用途是把函数的入口地址作为实参传递给形参,此函数的入口地址作为实参传递给形参,此时形参是指向函数的指针变量这样就能时形参是指向函数的指针变量这样就能够在被调用的函数中使用实参函数够在被调用的函数中使用实参函数 P2418.5.4 8.5.4 返回指针值的函数返回指针值的函数返回指针值的函数返回指针值的函数Ø一个函数也可以返回指针型的数据一个函数也可以返回指针型的数据 例如:例如: int *a(int x,int y); a是函数名,是函数名,*表示此函数值是指针表示此函数值是指针 最前面的最前面的int表示返回的指针是指向整型表示返回的指针是指向整型变量的 调用它以后能得到一个指向整型数据的调用它以后能得到一个指向整型数据的指针指针(地址地址)。
P2428.5.4 8.5.4 返回指针值的函数返回指针值的函数返回指针值的函数返回指针值的函数Ø返回指针值的函数一般定义形式为返回指针值的函数一般定义形式为 类型名类型名 *函数名函数名(参数表列参数表列);Ø这种形式与定义指向函数的指针变量很这种形式与定义指向函数的指针变量很相似,但请注意:在相似,但请注意:在*a两侧没有括号两侧没有括号有括号就成指向函数的指针变量了有括号就成指向函数的指针变量了P2428.5.5 8.5.5 指针数组指针数组指针数组指针数组Ø一个数组,若其元素均为指针类型数据,一个数组,若其元素均为指针类型数据,称为指针数组称为指针数组 例如:例如: int *p[4];Øp是数组,有是数组,有4个元素个元素Ø*表示此数组是指针类型的,每个数组元表示此数组是指针类型的,每个数组元素(相当于一个指针变量)都可指向一素(相当于一个指针变量)都可指向一个整型变量个整型变量 P2428.5.5 8.5.5 指针数组指针数组指针数组指针数组Ø一维指针数组的定义的一般形式为一维指针数组的定义的一般形式为 类型名类型名数组名数组名[数组长度数组长度];P2428.5.5 8.5.5 指针数组指针数组指针数组指针数组Ø指针数组比较适合用来指向若干个字符指针数组比较适合用来指向若干个字符串,使字符串处理更加方便灵活串,使字符串处理更加方便灵活Ø可以分别定义一些字符串,然后用指针可以分别定义一些字符串,然后用指针数组中的元素分别指向各字符串数组中的元素分别指向各字符串Ø由于由于各字符串长度一般是不相等的各字符串长度一般是不相等的,所,所以比用二维数组节省以比用二维数组节省内存单元内存单元P2428.5.5 8.5.5 指针数组指针数组指针数组指针数组Ø图书馆有若干本书,想把书名放在一个数图书馆有若干本书,想把书名放在一个数组中,然后要对这些书目进行排序和查询组中,然后要对这些书目进行排序和查询P242Great WallFORTRANComputer designBASICFollow mename[0]name[1]name[2]name[3]name[4]8.5.5 8.5.5 指针数组指针数组指针数组指针数组Ø图书馆有若干本书,想把书名放在一个数图书馆有若干本书,想把书名放在一个数组中,然后要对这些书目进行排序和查询组中,然后要对这些书目进行排序和查询P242Great WallFORTRANComputer designBASICFollow mename[0]name[1]name[2]name[3]name[4]8.5.6 8.5.6 多重指针多重指针多重指针多重指针————指向指针的指针指向指针的指针指向指针的指针指向指针的指针Ø指向另一个指针数据的指针变量,称为指向另一个指针数据的指针变量,称为指向指针的指针。
指向指针的指针P243Great WallFORTRANComputer designBASICFollow mename[0]name[1]name[2]name[3]name[4]name8.5.6 8.5.6 多重指针多重指针多重指针多重指针————指向指针的指针指向指针的指针指向指针的指针指向指针的指针char **p; P243Great WallFORTRANComputer designBASICFollow mename[0]name[1]name[2]name[3]name[4]namepp=name+2; 。
