《善于利用指针》PPT课件.ppt_第1页
《善于利用指针》PPT课件.ppt_第2页
《善于利用指针》PPT课件.ppt_第3页
《善于利用指针》PPT课件.ppt_第4页
《善于利用指针》PPT课件.ppt_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

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

文档简介

第第8 8章章 善于利用指针善于利用指针 8.1 指针是什么 8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串 1.变量的“直接访问”方式: i 2000H 3 直接访问: 按变量的地址(即变量名)存取变量值的方式。 例如: int i=3; 讨论一个问题: A、B和C三人约定住宿在某旅馆。A先到达旅馆,在服务台登记 了房间,房间号是2010。然后,A电话通知了B,但没有通知C。 B怎样找到A呢? B可以直接到2010找到A. int i=3,j=6,k; printf(“%d”,i); 通过变量名i 找到i的地址 2000H,从而从 存储单元读取3 讨论一个问题: A、B和C三人约定住宿在某旅馆。A先到达旅馆, 在服务台登记了房间,房间号是2010。然后,A电话通知了B,但没 有通知C。 C怎样找到A呢? C可以从旅馆的服务台查询到A的房号2010,间接找到A。 将变量的地址放在另一个内存单元中,先到另一个内存单元中 取得变量的地址,再由变量的地址找到变量并进行数据存取(见下 图)。 2.变量的“间接访问”方式 间接访问方式: 3 i 2000H 2000H i_pointer 作用相当 服务台 int i=3,j=6,k; 定义特殊变量i_pointer 将i的地址 存到这里 间接存取 i_pointer= *i_pointer=50 ; 50 8.1 8.1 指针指针是什么是什么 地址: 内存中存储单元的编号。 指针:在C在语言中一个变量的地址称为该变量的“指针”。 例如: int a; /* int *p1, *p2; p1= p2= printf(“a=%d,b=%dn“,a,b); printf(“*p1=%d,*p2=%dn“,*p1,*p2); return 0; 8.2.1 8.2.1 使用指针变量的例子使用指针变量的例子 p1 如:int *p1, *p2; lint是为指针变量指定的“基类型”。 l基类型指定指针变量可指向的变量类型。 lp1,p2是指针变量名,而不是*p1,*p2 lp1可以指向整型变量,但不能指向其他类型变量。 例如:int a ; float b ; int *p; p = p = 正确 错误 8.2.3 8.2.3 怎样引用指针变量怎样引用指针变量 在引用指针变量时,可能有三种情况: l给指针变量赋值。如:p= l引用指针变量指向的变量。 如有 p= *p=1; 则执行printf(“%d”, *p); 输出1 l引用指针变量的值。如:printf(“%x”,p); 使p指向a *p相当于a 以十六进制输出 a的地址 8.2.3 8.2.3 怎样引用指针变量怎样引用指针变量 要熟练掌握两个有关的运算符: 1、 /*定义p为指向int类型变量的指针*/ m=200 ; p= /*将m的地址赋给指针变量p*/ p m 2010H 200 2010H p= /* p 指向整型变量 m*/ *p=200 ; /*将200赋给指针变量p所指向的变量m*/ p m 2010H 2010H 200 执行语句 *p=200; 指针变量的赋值: 变量的指针(地址)是一个无符号整数,可以将一个变量的 指针赋值给一个指针变量,但不能将一个整数直接赋值给一个指 针变量。 1、用变量的地址给指针变量赋值(求地址运算符 p1 = 注意:变量的类型必须与指针变量的类型相同。 2、用相同类型的指针变量赋值。 例如:int a, *p1, *p2; p1 = p2 = p1 ; 注意:指针变量若不赋值,则指针变量的值是随机的。 危险危险 8.2.3 8.2.3 怎样引用指针变量怎样引用指针变量 3、赋空值NULL 例如:int *p ; p =NULL ;或p 0 ; 指针变量赋空值NULL与不赋值的区别: (1)指针变量赋空值NULL,指向为0的单元,系统保证该 单元不作它用,表示指针变量值没有意义; 用途: 避免指针变量的非法引用,在程序中常作为状 态比较, 如果p=NULL就不能操作p,此时p无意义,只有 p!=NULL,即p指向有意义的空间,才能操作p所指向的 对象。 (2)指针变量不赋值,指针变量的值是随机的,指向也是 随机的,具有不确定性; 例 main( ) int i=10,b=3; int *p; *p=i; printf(“%d”,*p); 危险! 例 main( ) int i=10,k; int *p; p= *p=i; printf(“%d”,*p); 指针变量p 随机 指针变量必须先赋值,再使用 3 . 2000 2004 2006 2005 整型变量i 102001 2002 2003 整型变量b 10 4、void *类型指针 void *p; 表示不指定p是指向哪一 种类型数据的指针变量 使用时要进行强制类型转换 例如:int *p1; p1=( p1=(intint *)p; *)p; 取指针变量所指向地址内容: b = * p ; 存指针变量所指向地址内容: * p 50 ; 例如: main() int a = 5 , b = 3 , *p ; p = b = * p + 3 ; *p = 4 ; printf( “ a = %d , b = %d ” , a , b ) ; 4000 p a 2000 b 3100 *p 20003 5 运行结果: a = 4 , b = 8 84 5、指针变量的存取操作 注意: *p若出现在“”的右边或其他表达式中则为取内容 *p若出现在“”的左边则为存内容 例8.2 输入a和b两个整数,按先大后小的顺序输出a和b。 #include int main() int *p1,*p2,*p,a,b; printf(“please enter two integer numbers:“); scanf(“%d,%d“, p1= p2= if(a void main() int a = 5 , b = 8 ; int t ; printf(“a= %d , b = %dn” ,a ,b); t = a ; a = b ; b = t ; printf(“a= %d , b = %dn” ,a ,b); #include void main() int a = 5 , b = 8 ; int *pa = int t ; printf(“a= %d , b = %dn” ,a ,b); t = *pa ; *pa = *pb ; *pb = t ; printf(“a= %d , b = %dn” ,a ,b); 例题1:通过一个主函数来完整地实现交换a,b两个数算法 直接访问 间接访问 例题2:通过编写一个子函数实现两个数的交换 #include void swap( int x , int y ) int t ; t = x ; x = y ; y = t ; void main() int a = 3 , b = 5 ; swap( a , b ) ; printf(“a = %d , b = %d n” , a , b ); 5 a2010H b2B12H x3100H y3F02H 3 5 3 3 5 5 3 3 t4D24H 不能实现两个数的交换 参数之间是值传递,单向(从实参传递给形参) 例题3: #include void swap( int *x , int *y ) int t ; t = *y ; *y = *x ; *x = t ; void main() int a = 3 , b = 5 ; swap( printf(“a = %d , b = %d n” , a , b ); 5 a2010H b2B12H x3100H y3F02H 2010 2B12 3 3 3 5 t4A10H 5 能实现两个数的交换 8.2.4 8.2.4 指针变量作为函数参数指针变量作为函数参数 例题3: #include void swap( int *x , int *y ) int t ; t = *y ; *y = *x ; *x = t ; void main() int a = 3 , b = 5 ; swap( printf(“a = %d , b = %d n” , a , b ); 5 a2010 b2B12 3 3 3 5 c语言中实参变量和形参变量之间的数据传递是单向的“值传递” 方式。指针变量作函数参数也要遵循这一规则。调用函数不可能改 变实参指针变量的值,但是可以改变实参指针变量所指变量的值。 例题4: #include void swap( int *x , int *y ) int *t ; t = x ; x = y ; y = t ; void main() int a = 3 , b = 5 ; swap( printf(“a = %d , b = %d n” , a , b ); 5 a2010 b2B12 x3100 y3F02 2010 2B12 3 2B12 2010 t4C00 2010 不能实现两个数的交换 1.实参和形参都是指针变量 2.被调函数中修改指针所指向的空间的值(即修改*p的值) 指针作为参数应用的方式: void swap( int *x , int *y ) int t ; t = *y ; *y = *x ; *x = t ; void swap( int *x , int *y ) int *t ; t = x ; x = y ; y = t ; void main() int a = 3 , b = 5 ; swap( printf(“a = %d , b = %d n” , a , b ); /能实现交换功能的函数 /不能实现交换功能的函数 #include void swap( int *x , int *y ) int *t ; *t = *x ; *x = *y ; *y = *t ; void main() int a = 3 , b = 5 ; swap( printf(“a = %d , b = %d n” , a , b ); 有问题:指针变量有问题:指针变量t t 没有指向对象,语没有指向对象,语 句存在危险句存在危险 #include void swap( int *x , int *y ) int *t , w ; t = *t = *x ; *x = *y ; *y = *t ; void main() int a = 3 , b = 5 ; swap( printf(“a = %d , b = %d n” , a , b ); 能够实现两能够实现两 个数的交换个数的交换 例如: int a , *pa ; pa = 指针变量应用总结 要求:”*”后面必须是地址表达式 , int *p; p= 注意: 数组名a是数组首元素的地址。 “p=a;”的作用是“把a数组的首元素的地址赋给指 针变量p” 。 即 p p2=p1+3 ; 三个数组元素 低高 p1 a0 p2 a3 指针变量减去正整数 p-n (n为正整数) 指针向低地址方向移动n个数据存储单元,指向的新 地址为:原地址-sizeof(类型说明符)*n 例:float a5,*p1= p2=p1-2 ; 2个数组元素 p2 a1 p1 a3 低高 例:int a32,i, *p ; l 下标法对数组进行运算 for(i=0;i = 指针的关系运算是两个指针所指向的地址之间的 比较运算,相等,为同一变量地址,否则,为不同变量的 地址,运算产生的结果为 1 和 0。 注意: 指针应指向同一数组,否则比较无意义。 不同类型指针之间的比较无意义;指针与整型常量或 整型变量的比较无意义,唯整数 0 例外( 0 表示空 指针)。 例:有定义:double a5,*p1,*p2 ;p1,p2指向如图所示 np1=NULL 或 p1=0 或 !p1 判断p1是否为空指针 结果:0 a a0 a1 a2 a3 a4 p1 p2 计算: np1= =p2 判断p1,p2是否指向同一变量 结果:0 np1 int main() int a10; int i; int *p = a ; printf(“please enter 10 integer numbers:“); for(i=0;i int main() int a10; int i; int *p = a ; printf(“please enter 10 integer numbers:“); for(i=0;i int main() int a10; int *p,i; printf(“please enter 10 integer numbers:“); for(i=0;i int main() int *p,i,a10; p=a; printf(“enter 10 integer numbers:n“); for(i=0;i void inv(int x ,int n); int main() int i, a10=3,7,9,11,0,6,7,5,4,2; for(i=0;i void inv(int *x,int n); int main() int arr10,*p; for(p=arr;p void sort(int x ,int n); int main() int i,*p,a10; p=a; for(i=0;ixk) k=j; if(k!=i) t=xi;xi=xk;xk=t; void sort(int *x,int n) if (*(x+j)*(x+k) k=j; t=*(x+i);*(x+i)=*(x+k);*(x+k)=t; 在xi+1x9中,最大 数xk与xi对换 n总结: 指针变量与一维数组的关系 int *p 与 int a10 1.数组名a是指针(地址)常量 2.p=a; p+i ,a + i 是ai的地址( a0,a1,a2等价于一维数组名 1、 各行第0个元素的地址, 即 a: 行指针 a+i :移动i行,为i行行地址 ai: 元素指针, 为i行第0个(0列) 元素地址 n 二维数组中元素aij地址的表示: 指针变量小结 定义数组 int c310; (2)引用 c二维数组首地址 c+i第i行首地址 ci+j 或*(c+i)+j第i行j列元素地址 cij、*(c+i)j 或*(*(c+i)+j) 第i行j列元素值 二维数组的指针 (1)指向数组元素的指针变量(元素指针) 例: 用指针变量输出二维数组元素的值 #include int main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for( p=a0 ;p int main() char string=“I love China!“; printf(“%sn“,string); printf(“%cn“,string7); return 0; 例8.17 通过字符指针变量输出一个字符串常量。 #include int main() char *string=“I love China!“; printf(“%sn“,string); return 0; char *string; string=” I love China!”; 将字符串“I love China!” 的首地址赋给指针 变量string 例8.18 将字符串a复制为字符串b,然后输出字符串b。 #include int main() char a =“I am a student.“,b20; int i; for(i=0;*(a+i)!=0;i+) *(b+i)=*(a+i); *(b+i)=0; printf(“string a is:%sn“,a); printf(“string b is:“); for(i=0;bi!=0;i+) printf(“%c“,bi); printf(“n“); return 0; 添加代码实现字符串复制 重要代码 添加代码输出字符数组b 例8.19 用指针变量来处理例8.18问题。 #include int main() char a=“I am a boy.“,b20,*p1,*p2; for(p1=a;p2=b;*p1!=0;p1+,p2+) *p2=*p1; *p2=0; printf(“string a is:%sn“,a); printf(“string b is:%sn“,b); return 0; 添加代码实现使用指针实现字符数组复制 8.4.2 8.4.2 字符指针作函数参数字符指针作函数参数 如果想把一个字符串从一个函数“传递”到另一个函数,可以用 指针实现。 将一个字符串从一个函数传递到另一个函数,可以使用传地址 的方式,即用字符数组名或字符指针变量作参数。有以下四种 情况: 实参 形参 1 数组名 数组名 2 数组名 字符指针变量 3 字符指针变量 字符指针变量 4 字符指针变量 数组名 例8.20 用函数调用实现字符串的复制。 (1) 用字符数组名作为函数参数 #include void copy_string(char from,char to); int main() char a=“I am a teacher.“; char b=“you are a student.“; printf(“a=%snb=%sn“,a,b); printf(“copy string a to string b:n“); copy_string(a,b); printf(“a=%snb=%sn“,a,b); return 0; 实参是数组名 void copy_string(char from, char to) int i=0; while(fromi!=0) toi=fromi; i+; toi=0; 形参是数组 (2)用字符型指针变量作实参 #include void copy_string(char from, char to); int main() char a=“I am a teacher.”; char b=“you are a student.”; char *from=a,*to=b; printf(“a=%snb=%sn“,a,b); printf(“ncopy string a to string b:n“); copy_string(from,to); printf(“a=%snb=%sn“,a,b); return 0; 实参是指针变量 (3)用字符指针变量作形参和实参 #include void copy_string(char *from, char *to); int main() char *a=“I am a teacher.”; char b=“You are a student.”; char *p=b; printf(“a=%snb=%sn”,a,b); printf(“ncopy string a to string b:n“); copy_string(a,p); printf(“a=%snb=%sn”,a,b); return 0; 实参是指针变量 void copy_string(char *from, char *to) for( ;*from!=0; from+,to+) *to=*from; *to=0; 形参是指针变量 8.4.3 8.4.3 使用字符指针变量和字符数组的比较使用字符指针变量和字符数组的比较 注意字符数组与字符指针变量的区别。 (1) 字符数组由若干个元素组成,每个元素中放一个字符,而字符 指针变量中存放的是地址(字符串第1个字符的地址),并不是将 字符串存放在字符指针变量中。 (2) 可以对字符指针变量赋值,但不能对数组名赋值。 char *a; a=”I love China!”; char str14;str0=I; char str14; str=”I love China!”; 正确 正确 错误 str是数组名(指针常量),不能给常量赋值 8.4.3 8.4.3 使用字符指针变量和字符数组的比较使用字符指针变量和字符数组的比较 (3)初始化。 char *a=”I love China!”; char *a; a=”I love China!”; char a14= ”I love China ”; char a14; a=”I love China ”; (4) 存储单元的内容。 编译时为字符数组分配若干存储单元,以存放各元素的值, 而对字符指针变量,只分配一个存储单元存放地址。 char *a; scanf(“%s”,a); char *a,str10; a=str;scanf (“%s”,a); 正确 正确 正确 错误 错误 正确 除了定义时,不能用赋 值语句给数组整体赋值 8.4.3 8.4.3 使用字符指针变量和字符数组的比较使用字符指针变量和字符数组的比较 (5) 指针变量的值是可以改变的,而数组名代表一个

温馨提示

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

评论

0/150

提交评论