C语言指针学习谭浩强版_第1页
C语言指针学习谭浩强版_第2页
C语言指针学习谭浩强版_第3页
C语言指针学习谭浩强版_第4页
C语言指针学习谭浩强版_第5页
已阅读5页,还剩87页未读 继续免费阅读

下载本文档

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

文档简介

1、8.1 指指针针是什么是什么8.2 指针变量指针变量8.3 通过指针引用数组通过指针引用数组8.4 通过指针引用字符串通过指针引用字符串1.1.变量的变量的“直接访问直接访问”方式:方式:i i2000H2000H3 3直接访问直接访问: : 按变量的地址(即变量名)存取变量值的方式。按变量的地址(即变量名)存取变量值的方式。 例如:例如: intint i=3; i=3;讨论一个问题:讨论一个问题: A A、B B和和C C三人约定住宿在某旅馆。三人约定住宿在某旅馆。A A先到达旅馆,在服务台登记先到达旅馆,在服务台登记了房间,房间号是了房间,房间号是20102010。然后,。然后,A A电

2、话通知了电话通知了B B,但没有通知,但没有通知C C。 B B怎样找到怎样找到A A呢?呢? B B可以可以直接直接到到20102010找到找到A.A.int i=3,j=6,k;printf(“%d”,i);通过变量名通过变量名i找到找到i的地址的地址2000H,从而,从而从从存储单元存储单元读读取取3讨论一个问题:讨论一个问题: A A、B B和和C C三人约定住宿在某旅馆。三人约定住宿在某旅馆。A A先到达旅馆,先到达旅馆,在服务台登记了房间,房间号是在服务台登记了房间,房间号是20102010。然后,。然后,A A电话通知了电话通知了B B,但没,但没有通知有通知C C。 C C怎样

3、找到怎样找到A A呢?呢? C C可以从旅馆的服务台查询到可以从旅馆的服务台查询到A A的房号的房号20102010,间接间接找到找到A A。 将变量的地址放在另一个内存单元中,先到另一个内存单元中将变量的地址放在另一个内存单元中,先到另一个内存单元中取得变量的地址,再由变量的地址找到变量并进行数据存取取得变量的地址,再由变量的地址找到变量并进行数据存取( (见下见下图图) )。2.2.变量的变量的“间接访问间接访问”方式方式间接访问方式间接访问方式: :3 3i i2000H2000H2000H2000Hi_pointeri_pointer作用相当服务台int i=3,j=6,k;定义特殊变

4、量定义特殊变量i_pointer将将i的地址的地址存到这里存到这里间接存取间接存取i_pointer=&i;*i_pointer=50;5050 地址地址: 内存中存储单元的编号。内存中存储单元的编号。 指针:指针:在在C在语言中一个变量的地址称为该变量的在语言中一个变量的地址称为该变量的“指针指针”。 例如例如: int a; /* &a即为变量即为变量a的地址的地址(指针指针) */ 8.2.1使用指针变量的例子使用指针变量的例子8.2.2 怎样定义指针变量怎样定义指针变量8.2.3 怎样引用指针变量怎样引用指针变量8.2.4 指针变量作为函数参数指针变量作为函数参数 例例

5、8.1 通过指针变量访问整型变量。通过指针变量访问整型变量。#include int main() int a=100,b=10; int *p1, *p2; p1=&a; p2=&b; printf(a=%d,b=%dn,a,b); printf(*p1=%d,*p2=%dn,*p1,*p2); return 0;p1 &a*p1 a/ / 定义整型变量,并初始化定义整型变量,并初始化/ / 定义指向整型数据的指针变量定义指向整型数据的指针变量/ / 为指针变量为指针变量p1p1赋值赋值/ / 为指针变量为指针变量p2p2赋值赋值定义指针变量的一般形式为:定义指针变量

6、的一般形式为: 类型类型 * 指针变量名指针变量名; 如:如:int *p1, *p2;lint是是为为指针变量指定的指针变量指定的“基类型基类型”。l基类型指定指针变量可指向的变量类型基类型指定指针变量可指向的变量类型。lp1,p2是指针变量名,而不是是指针变量名,而不是*p1,*p2l如如p1可以指向整型变量,但不能指向浮点型变量可以指向整型变量,但不能指向浮点型变量。例如:例如:int a ; float b ; int *p; p = &a ; p = &b ;正确正确错误错误在引用指针变量时,可能有三种情况:在引用指针变量时,可能有三种情况:l给指针变量赋值。如:给指

7、针变量赋值。如:p=&a;l引用指针变量指向的变量引用指针变量指向的变量。 如如有有 p=&a; *p=1; 则执行则执行printf(“%d”, *p); 输出输出1l引用指针变量的值。如:引用指针变量的值。如:printf(“%x”,p);使使p指向指向a*p相当于相当于a以以十六十六进制输出进制输出a的地址的地址要熟练掌握两个有关的运算符:要熟练掌握两个有关的运算符:1、& 取址运算取址运算功能:返回其后随变量的内存功能:返回其后随变量的内存地址地址例:例:int *p ,m ; /*定义定义p为指向为指向int类型变量的指针类型变量的指针*/ m=200 ; p

8、=&m ; /*将将m的地址赋给指针变量的地址赋给指针变量p*/pm 2010H 2002010H&m要熟练掌握两个有关的运算符:要熟练掌握两个有关的运算符:2、* 间接存取运算间接存取运算 功能:返回其后随地址功能:返回其后随地址(指针变量值指针变量值)中的中的变量值变量值例:例:int *p ,m ; p=&m ; /* p 指向整型变量指向整型变量 m*/ *p=200 ; /*将将200赋给指针变量赋给指针变量p所指向的变量所指向的变量m*/pm&m200执行语句执行语句*p=200; 指针变量的赋值:指针变量的赋值: 变量的指针(地址)是一个无符号整数

9、,可以将一个变量的变量的指针(地址)是一个无符号整数,可以将一个变量的指针赋值给一个指针变量,指针赋值给一个指针变量,但不能将一个整数直接赋值给一个指但不能将一个整数直接赋值给一个指针变量针变量。 1 1、用变量的地址给指针变量赋值、用变量的地址给指针变量赋值( (求地址运算符求地址运算符&)&)。 例如:例如:intint a, b, a, b, * *p1;p1; p1 = &a ; p1 = &a ; 注意:注意:变量的类型必须与指针变量的类型相同。变量的类型必须与指针变量的类型相同。 2 2、用相同类型的指针变量赋值。、用相同类型的指针变量赋值。 例如例

10、如:intint a, a, * *p1, p1, * *p2;p2; p1 = &a ; p1 = &a ; p2 = p1 ; p2 = p1 ; 注意:注意:指针变量若不赋值,则指针变量的值是随机的。指针变量若不赋值,则指针变量的值是随机的。例例 main( ) int i=10,b=3; int *p; *p=i; printf(“%d”,*p); 危险!危险!例例 main( ) int i=10,k; int *p; p=&k; *p=i; printf(“%d”,*p); 指针变量指针变量p随机随机指针变量必须先赋值指针变量必须先赋值, ,再使用再使用3.

11、2000200420062005整型变量整型变量i10200120022003整型变量整型变量b10(2)(2)指针变量不赋值,指针变量的值是随机的,指向也指针变量不赋值,指针变量的值是随机的,指向也是随机的,具有不确定性;是随机的,具有不确定性;3 3、赋空值、赋空值NULLNULL例如:例如:intint * *p ;p ;p =NULL ;p =NULL ;或或p p 0 ;0 ;指针变量赋空值指针变量赋空值NULLNULL与不赋值的区别:与不赋值的区别:(1)(1)指针变量赋空值指针变量赋空值NULLNULL,指向为指向为0 0的单元,系统保证该的单元,系统保证该单元不作它用,表示指针

12、变量值没有意义;单元不作它用,表示指针变量值没有意义; 用途用途: :避免指针变量的非法引用,在避免指针变量的非法引用,在程序中常作为状程序中常作为状态比较态比较4 4、void void * *类型指针类型指针void void * *p;p;表示不指定表示不指定p p是指向哪一是指向哪一种类型数据的指针变量种类型数据的指针变量使用时要进行强制类型转换使用时要进行强制类型转换取指针变量所指向地址内容:取指针变量所指向地址内容:b = * p ;存指针变量所指向地址内容:存指针变量所指向地址内容: * p 50 ;例如:例如:main() int a = 5 , b = 3 , *p ; p

13、= &a ; b = * p + 3 ; *p = 4 ; printf( “ a = %d , b = %d ” , a , b ) ;4000pa2000b3100*p200035运行结果:运行结果:a = 4 , b = 8 84注意:注意:*p若出现在若出现在“”的的右边右边或其他表达式中则为或其他表达式中则为取内取内容容*p若出现在若出现在“”的的左边左边则为则为存内容存内容 例例8.2 输入输入a和和b两个整数,按先大后小的顺序输出两个整数,按先大后小的顺序输出a和和b。#include int main() int *p1,*p2,*p,a,b; printf(pleas

14、e enter two integer numbers:); scanf(%d,%d,&a,&b); p1=&a; p2=&b; if(ab) p=p1;p1=p2;p2=p; printf(a=%d,b=%dn,a,b); printf(max=%d,min=%dn,*p1,*p2); return 0;#include 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”

15、 ,a ,b);#include void main() int a = 5 , b = 8 ; int *pa = &a , *pb = &b ; 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

16、 ; t = x ; x = y ; y = t ;void main() int a = 3 , b = 5 ; swap( a , b ) ; printf(“a = %d , b = %d n” , a , b );5a2010Hb2B12Hx3100Hy3F02H3533 55 33t4D24H不能实现两个数的交换不能实现两个数的交换参数之间是值传递,单向(从实参传递给形参)参数之间是值传递,单向(从实参传递给形参)例题例题3:#include void swap( int *x , int *y ) int t ; t = *y ; *y = *x ; *x = t ;void ma

17、in() int a = 3 , b = 5 ; swap( &a , &b ) ; printf(“a = %d , b = %d n” , a , b );5a2010Hb2B12Hx3100Hy3F02H20102B123 33 5t4A10H 5能实现两个数的交换能实现两个数的交换例题例题3:#include void swap( int *x , int *y ) int t ; t = *y ; *y = *x ; *x = t ;void main() int a = 3 , b = 5 ; swap( &a , &b ) ; printf(“a

18、= %d , b = %d n” , a , b );5a2010b2B123 33 5 c语言中实参变量和形参变量之间的数据传递是单向的语言中实参变量和形参变量之间的数据传递是单向的“值传递值传递”方式。指针变量作函数参数也要遵循这一规则。调用函数不可能改方式。指针变量作函数参数也要遵循这一规则。调用函数不可能改变实参指针变量的值,但是可以改变实参指针变量所指变量的值。变实参指针变量的值,但是可以改变实参指针变量所指变量的值。例题例题4:#include void swap( int *x , int *y ) int *t ; t = x ; x = y ; y = t ;void mai

19、n() int a = 3 , b = 5 ; swap( &a , &b ) ; printf(“a = %d , b = %d n” , a , b );5a2010b2B12x3100y3F0220102B123 2B12 2010t4C00 2010不能实现两个数的交换不能实现两个数的交换1.实参和形参都是指针变量实参和形参都是指针变量2.被调函数中修改指针所指向的空间的值(即修改被调函数中修改指针所指向的空间的值(即修改*p的值)的值)指针作为参数,地址传递的条件:指针作为参数,地址传递的条件:void swap( int *x , int *y ) int t ;

20、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( &a , &b ) ; printf(“a = %d , b = %d n” , a , b );/能实现交换功能的函数能实现交换功能的函数/不能实现交换功能的函数不能实现交换功能的函数#include void swap( int *x , int *y ) int *t ; *t = *x ; *x = *y ; *y = *

21、t ;void main() int a = 3 , b = 5 ; swap( &a , &b ) ; printf(“a = %d , b = %d n” , a , b );#include void swap( int *x , int *y ) int *t , w ; t = &w ; *t = *x ; *x = *y ; *y = *t ;void main() int a = 3 , b = 5 ; swap( &a , &b ) ;printf(“a = %d , b = %d n” , a , b );指针变量的指针变量的种类种类指

22、针变量的值指针变量的值指向对象的值表达形指向对象的值表达形式式指向变量的指向变量的指针变量指针变量pa = &apa = &a* *pa = a pa = a 例如例如: int a , *pa ; pa = &a ;指针变量说明表格指针变量说明表格要求:要求:”*”后面必须是地址表达式后面必须是地址表达式 , &后面是变量后面是变量*和和& 运算符的关系:运算符的关系:互为逆运算互为逆运算8.3.1 数组元素的指针数组元素的指针8.3.2 在引用数组元素时指针的运算在引用数组元素时指针的运算8.3.3 通过指针引用数组元素通过指针引用数组元素8.3.4

23、 用数组名作函数参数用数组名作函数参数8.3.5 通过指针引用多维数组通过指针引用多维数组数组元素在内存中是连续存放的数组元素在内存中是连续存放的一个数组包含若干元素,每个数组元素都有相应的地址一个数组包含若干元素,每个数组元素都有相应的地址。intint a10 ; a10 ; 数组数组a a中下标为中下标为i(i(假设假设i i的取值合理的取值合理) )的数组元素的地址:的数组元素的地址:&ai第二种表达形式:第二种表达形式:C语言中数组中下标为语言中数组中下标为0的数组元素地址为:的数组元素地址为:数组名数组名 或或 数组名数组名 + 0C语言中数组中下标为语言中数组中下标为i的

24、数组元素地址为:的数组元素地址为:数组名数组名 + i所谓数组元素的指针就是数组元素的地址所谓数组元素的指针就是数组元素的地址。指针变量可以指向数组元素(把某一元素的地址放到一指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中)个指针变量中)。 可以用一个指针变量指向一个数组元素可以用一个指针变量指向一个数组元素 int a10=1,3,5,7,9,11,13,15,17,19; int *p; p=&a0;注意注意:数组名数组名a是是数组首元素的地址数组首元素的地址,是一级指针是一级指针。“p=a;”的作用是的作用是“把把a数组的首元素的地数组的首元素的地址赋给指针变量址赋

25、给指针变量p” 。 即即 p &a0 a在指针指向数组元素时,在指针指向数组元素时,允许允许以下运算:以下运算:l加一个整数加一个整数(用用+或或+=),如,如p+1p 计算计算p+p+低低高高p+ = p指向下一指向下一数据数据存储单元(向后移动存储单元(向后移动4个字节)个字节)+:指针向高地址方向移动一个数据存储单元:指针向高地址方向移动一个数据存储单元pp在指针指向数组元素时,在指针指向数组元素时,允许允许以下运算:以下运算:l减一个整数减一个整数(用用-或或-=),如,如p-1p-:指针向低地址方向移动一个数据存储单元:指针向低地址方向移动一个数据存储单元p = p指向前一指

26、向前一数据数据存储存储单元(向前移动单元(向前移动4个字节)个字节) 计算计算p p低低高高pp注意:数据类型不同,指针增注意:数据类型不同,指针增1和减和减1运算所引起的运算所引起的 地址变化量是不同的,指向的新地址为:地址变化量是不同的,指向的新地址为: 原地址原地址 sizeof(类型说明符类型说明符)例:例:int a32,i *p ;l 下标法对数组进行运算下标法对数组进行运算 for(i=0;i32;i+) scanf(“%d”,&ai); l 指针法对数组进行运算指针法对数组进行运算 p=a ; for(i=0;i32;i+) scanf(“%d”,p+);例:例:int

27、 a10,*p ; p=&a2 ; 计算:计算:+p 表达式值表达式值为为&a3,p的值为的值为&a3 计算:计算:p+ 表达式值为表达式值为&a2,p的值为的值为&a3在指针指向数组元素时,在指针指向数组元素时,允许允许以下运算:以下运算:l加减一个正整数加减一个正整数n ,如如p+n(或(或p-n)指针向高地址方向移动指针向高地址方向移动n个数据存储单元个数据存储单元,指向的新指向的新地址为:地址为:原地址原地址+sizeof(类型说明符类型说明符)*n例:例:float a5,*p1=&a0,*p2 ; p2=p1+3 ; 三个数组元素三个

28、数组元素低低高高p1a0p2a3指针变量减去正整数指针变量减去正整数 p-n (n为正整数为正整数) 指针向低地址方向移动指针向低地址方向移动n个数据存储单元个数据存储单元,指向的新指向的新地址为:原地址地址为:原地址-sizeof(类型说明符类型说明符)*n例:例:float a5,*p1=&a3,*p2 ; p2=p1-2 ; 2个数组元素个数组元素p2a1p1a3低低高高在指针指向数组元素时,在指针指向数组元素时,允许允许以下运算:以下运算:l自加运算,如自加运算,如p+,+pl自减运算,如自减运算,如p-,-pl两个指针相减,如两个指针相减,如p1-p2 (只有只有p1和和p2

29、都指向同一数组中的元都指向同一数组中的元素时才有意义素时才有意义)(1) 如果指针变量如果指针变量p已指向数组中的一个元素,则已指向数组中的一个元素,则p+1指向同一指向同一数组中的下一个元素,数组中的下一个元素,p-1指向同一数组中的上一个元素。指向同一数组中的上一个元素。 float a10,*p=a; 假设假设a0的地址为的地址为2000,则,则lp的值为的值为2000lp+1的值为的值为2004lP-1的值为的值为1996越界越界(2) 如果如果p的初值为的初值为&a0,则,则p+i和和a+i就是数组元就是数组元素素ai的地址,或者说,它的地址,或者说,它们指向们指向a数组序号

30、为数组序号为i的元素的元素a0a1a2a3a4a5a6a7a8a9pp+1,a+1 p+i,a+i p+9,a+9 若若p=a , 即:即:p+i a+i &ai (3) *(p+i)或或*(a+i)是是p+i或或a+i所指向的数组元素,即所指向的数组元素,即ai。a0a1a2a3a4a5a6a7a8a9pp+1,a+1 p+i,a+i p+9,a+9 *(p+i)若若p=a , 即:即:*(p+i) *(a+i) ai (4) 如果指针如果指针p1和和p2都指向都指向同一数组同一数组 p2-p1的值的值是是4。 p1+p2无意义。无意义。a0a1a2a3a4a5a6a7a8a9p1p

31、2 如果两个指针变量指向同一个数组的如果两个指针变量指向同一个数组的元素,则两个指针变量之差元素,则两个指针变量之差表示两个指表示两个指针指向的内存位置之间相隔多少个元素针指向的内存位置之间相隔多少个元素(注意是元素,并不是字节数注意是元素,并不是字节数)(5)(5)指针的关系运算指针的关系运算 = != = = != = 指针的关系运算是两个指针所指向的地址之间的指针的关系运算是两个指针所指向的地址之间的比较运算,相等,为同一变量地址,否则,为不同变量的比较运算,相等,为同一变量地址,否则,为不同变量的地址,运算产生的结果为地址,运算产生的结果为 1 1 和和 0 0。注意:注意:指针应指向

32、同一数组,否则比较无意义。指针应指向同一数组,否则比较无意义。不同类型指针之间的比较无意义不同类型指针之间的比较无意义; ;指针与整型常量或指针与整型常量或整型变量的比较无意义,唯整数整型变量的比较无意义,唯整数 0 0 例外例外( 0 ( 0 表示空表示空指针指针) )。例:有定义:例:有定义:double a5,*p1,*p2 ;p1,p2指向如图所示指向如图所示np1=NULL 或或 p1=0 或或 !p1 判断判断p1是否为空指针是否为空指针 结果结果:0aa0a1a2a3a4p1p2计算:计算:np1= =p2 判断判断p1,p2是否指向同一变量是否指向同一变量 结果结果:0np1p

33、2 指向前面元素的指针变量地址值小指向前面元素的指针变量地址值小 结果:结果:1np1!=0 或或 p1 功能同上,结果相反功能同上,结果相反 结果:结果:1低地址低地址高地址高地址第第i i个元素地址的表示个元素地址的表示(p(p的初值为的初值为a)a) : a+i a+i 数组名法数组名法 p+i p+i 指针法指针法 &ai &ai 下标法下标法 &pi&pi第第i i个元素值的表示个元素值的表示(p(p的初值为的初值为a)a) : * *(a+i) (a+i) 数组名法数组名法 * *(p+i) (p+i) 指针法指针法 ai ai 下标法下标法 pip

34、i 下标法下标法a9aa0a1.ai用指针和数组名访问内存方式的用指针和数组名访问内存方式的重要区别重要区别: :1.1.指针变量是地址变量,指针变量是地址变量,其其指向由所赋值确定指向由所赋值确定2.2.数组名是地址常量(指针常量)数组名是地址常量(指针常量),恒定指向,恒定指向 数组的第数组的第0 0个元素个元素p=a;p+;p=p+5p=a;p+;p=p+5; ; a=&a5;a+a=&a5;a+ ; ;pi i个元素个元素a+i总结总结正确正确错误错误设设 int a5 , *p = a ; 指针变量指针变量数组指针数组指针下标法下标法地址关系:地址关系: p a &a

35、mp;a 0 &p 0 p + 1 a + 1 &a 1 &p 1 p + 2 a + 2 &a 2 &p2 p + 3 a + 3 &a 3 &p3 p + 4 a + 4 &a 4 &p412340a0a1a4.2C002468ap下标法下标法内容关系:内容关系:设设 int a5 , *p = a ; 指针法指针法数组名数组名下标法下标法 *( p) *( a) a 0 p 0 *(p + 1) *( a + 1) a 1 p 1 *(p + 2) *(a + 2) a 2 p2 *( p + 3) *( a + 3

36、) a 3 p3 *(p + 4) *( a + 4) a 4 p412340a0a1a4.2C002468ap下标法下标法 引用一个数组元素,可用下面两种方法:引用一个数组元素,可用下面两种方法: 其中其中a是数组名,是数组名,p是指向数组元素的指针变量,其初值是指向数组元素的指针变量,其初值p=a。 ()() 下标法下标法 如如ai、pi形式形式 ()() 指针法指针法 如如*(a+i)或或*(p+i) 例例8.6 有一个整型数组有一个整型数组a,有,有10个元素,要求输出数组中的全部个元素,要求输出数组中的全部元素。元素。 解题思路:引用数组中各元素的值有解题思路:引用数组中各元素的值有

37、3种方法:种方法:u(1)下标法下标法;u(2)通过数组名计算数组元素地址,找出元素的值通过数组名计算数组元素地址,找出元素的值;u(3) 用指针变量指向数组元素用指针变量指向数组元素(1) 下标法。下标法。 #include int main() int a10; int i; int *p = a ; printf(please enter 10 integer numbers:); for(i=0;i10;i+) scanf(%d,&ai); for(i=0;i10;i+) printf(%d ,ai); printf(%n); return 0; 下标法下标法for(i=0;i

38、10;i+) printf(%d ,pi );(2) 通过数组名计算数组元素地址,找出元素的值通过数组名计算数组元素地址,找出元素的值#include int main() int a10; int i; int *p = a ; printf(please enter 10 integer numbers:); for(i=0;i10;i+) scanf(%d,&ai); for(i=0;i10;i+) printf(%d ,*(a+i); printf(n); return 0; 指针指针法法for(i=0;i10;i+) printf(%d ,*(p+i) );(3) 用指针变量

39、指向数组元素用指针变量指向数组元素 #include int main() int a10; int *p,i; printf(please enter 10 integer numbers:); for(i=0;i10;i+) scanf(%d,&ai); for(p=a;p(a+10);p+) printf(%d ,*p); printf(n); return 0;for(i=0;i10;a+,i+) printf(“%d ”,*a); 错!错!数组名是常量,不可以修改值数组名是常量,不可以修改值指针变量指针变量法法 例例8.7 通过指针变量输出整型数组通过指针变量输出整型数组a的

40、的10个元素。个元素。#include int main() int *p,i,a10; p=a; printf(“enter 10 integer numbers:n); for(i=0;i10;i+) scanf(“%d”,p+); p=a; for(i=0;i10;i+,p+) printf(“%d ”,*p); printf(n); return 0;是否可以省略是否可以省略? 用数组名作函数参数用数组名作函数参数时,因为时,因为实参数组名代表该数组首元素的地实参数组名代表该数组首元素的地址址,形参应该是一个指针变量形参应该是一个指针变量。 C编译都是将形参数组名作为指针变量来处理的编

41、译都是将形参数组名作为指针变量来处理的。void fun(int arr,int n);int main() int array10; fun (array,10); return 0; void fun(int arr ,int n) void fun(int *arr,int n)array0arr0array数组数组arrarray3arr3arr+3*arr例例8.8 将数组将数组a中中n个整数按相反顺序存放个整数按相反顺序存放解题思路:将解题思路:将a0与与an-1对换,对换,将将a4与与a5对换。对换。ji23ji59ji47ji711ji60例例8.8 将数组将数组a中中n个整数

42、按相反顺序存放个整数按相反顺序存放#include void inv(int x ,int n);int main() int i, a10=3,7,9,11,0,6,7,5,4,2; for(i=0;i10;i+) printf(“%d ”,ai); printf(n); inv(a,10); for(i=0;i10;i+) printf(“%d ”,ai); printf(n); return 0;void inv(int x ,int n) int temp,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; temp=xi;xi=xj;xj=temp; vo

43、id inv(int x ,int n) int temp,*i,*j; for(i=x, j=x+n-1; ij; i+,j-) temp=*i; *i=*j; *j=temp; 例例8.9 改写例改写例8.8,用指针变量作实参。,用指针变量作实参。#include void inv(int *x,int n);int main() int arr10,*p; for(p=arr;parr+10;p+) scanf(“%d”,p); p=arr; inv(p,10); for(p=arr;parr+10;p+) printf(“%d ”,*p); printf(n); return 0;例例

44、8.10 用指针方法对用指针方法对10个整数按由大到小顺序排序。个整数按由大到小顺序排序。#include void sort(int x ,int n);int main() int i,*p,a10; p=a; for(i=0;i10;i+) scanf(“%d”,p+); p=a; sort(p,10); for(p=a;pa+10;p+) printf(“%d ”,*p); printf(n); return 0;void sort(int x,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jxk) k=j; if(k!=i)

45、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;在在xix9中,中,最最大大数数xk与与xi对换对换n总结:总结: 一级指针变量与一维数组的关系一级指针变量与一维数组的关系int *p 与与 int a101.数组名数组名a是指针(地址)常量是指针(地址)常量2.p=a; p+i ,a + i 是是ai的地址的地址(&ai)3.数组元素的表示方法数组元素的表示方法:下标法和指针法下标法和指针法即若即若p=a, 则则 p i a i *( p + i

46、) *( a + i )4.形参数组实质上是指针变量,即形参数组实质上是指针变量,即int a int *a5.在定义指针变量(不是形参)时,不能把在定义指针变量(不是形参)时,不能把int *p 写成写成int p;系统只给系统只给p分配能保存一个指针值的内存区;分配能保存一个指针值的内存区;而给数组分配而给数组分配4*10字节的内存区字节的内存区(VC中中)Int a34;aa0a1a2a00a01a02a03a10a11a12a13a20a21a22a23444例如,把例如,把a看作是一个一维数组,它有看作是一个一维数组,它有3个元素:个元素: a0、a1、a2每个元素又是一个包含每个元

47、素又是一个包含4个元素的一维数组个元素的一维数组相当一维相当一维数组名数组名二维数组名二维数组名 + 行下标,如行下标,如a0,a+1,a+2 1、二维数组每行的行地址,二维数组每行的行地址, 即第即第0行,第行,第1行,第行,第2行的行地址行的行地址 2、 VC中中a+1移动移动16个字节即一行个字节即一行 aa0a+1a1a+2a2a0+1 a0+2 a0+3i i行行j j列列a0+08.3.5 8.3.5 多维数组与指针多维数组与指针 intint a34; a34; a0,a1,a2等价于等价于一一维数组名维数组名 1、 各行第各行第0个元素的地址个元素的地址, 即即&a00

48、, &a10, &a202、VC中中ai+1移动移动4个字节个字节,即一个元素即一个元素(列列)aa0a+1a1a+2a2a0+1 a0+2 a0+3i i行行j j列列a0+08.3.5 8.3.5 多维数组与指针多维数组与指针 n行指针和元素指针行指针和元素指针 int a34;a: 行指针行指针 a+i :移动移动i行行,为为i行行地址行行地址ai: 元素元素指针指针, 为为i行第行第0个个(0列列) 元素地址元素地址&ai0 ai+j: 移动移动j列列,为元素为元素aij的地址的地址&aijaa0a+1a1a+2a2a0+1 a0+2 a0+3i i行行

49、j j列列a0+0 ai *(a+i) *(a+i) 为为i行首元素的地址,即行首元素的地址,即&ai0 *(a+i)+j 移动移动j列,即列,即&aijaa0a+1a1a+2a2a0+1 a0+2 a0+3i i行行j j列列a0+0说明:说明:a+i,ai,a+i,ai,* *(a+i)(a+i)等等都不是实际变量都不是实际变量, ,它们不占它们不占用内存单元用内存单元, ,只是地址运算只是地址运算中的各种不同表示中的各种不同表示注意注意: a+ia+i是第是第i i行的行地址,行的行地址, aiai即即* *(a+i)(a+i)是元素是元素ai0ai0的地址。的地址。n

50、二维数组中元素二维数组中元素aijaij地址的表示:地址的表示: &aij &aij ai+j ai+j * *(a+i)+j(a+i)+j &a00+m&a00+m* *i+j i+j ( (设二维数组有设二维数组有m m列列) )n 二维数组中元素的引用方法:二维数组中元素的引用方法: aij aij * *(ai+j) (ai+j) * *( (* *(a+i)+j) (a+i)+j) ( (* *(a+i)j(a+i)j * *(&a00+m(&a00+m* *i+j)i+j)二维数组的指针二维数组的指针(1)指向数组元素的指针变量指向数

51、组元素的指针变量(元素指针元素指针)例例: 用指针变量输出二维数组元素的值用指针变量输出二维数组元素的值#includeint main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for( p=a0 ;pa0+12 ;p+) if(p-a0 )%4=0) printf(n); printf(%4d,*p); printf(n); return 0; 注意数据类型的一致,注意数据类型的一致,不能写为不能写为p=a;p=a;元素指针元素指针p p的的移动范围移动范围指针变量小结指针变量小结一级指针一级指针(1)一级指针定义一级指针定义 in

52、t a , b10 , * p;(2)(2)一级指针定义赋值一级指针定义赋值 p = &a ; p = &a ; p = &b3 ; p = &b3 ; 若若p=b;p=b; / / 请给出数组请给出数组b b下标为下标为5 5数组元素值表达式数组元素值表达式 / p / p 指向指向a a变量变量 / p / p 指向指向b3b3数组元素数组元素 或或 p = b + 3 ;p = b + 3 ;(3)(3)规则规则定义定义标识符时标识符时, ,若标识符两侧运算符若标识符两侧运算符* *+=1+=1引用引用一级指针时,一级指针时,该标识符是一级指针该标识符是一

53、级指针引用的是指向的地址引用的是指向的地址若标识符两侧运算符若标识符两侧运算符* *+=0+=0引用的是指向地址中值引用的是指向地址中值若标识符两侧运算符若标识符两侧运算符* *+=1+=1注意:以上总结仅限于标识符两侧仅有注意:以上总结仅限于标识符两侧仅有* *,两个运算符两个运算符 若若p=b;p=b; / / 请给出数组请给出数组b b下标为下标为5 5数组元素值表达式数组元素值表达式 p5,b5, p5,b5,* *(p+5),(p+5),* *(b+5)(b+5)指针变量小结指针变量小结二级指针二级指针(1)二级指针二级指针 int c310;(2)(2)引用引用定义定义标识符时,若

54、标识符两侧运算符标识符时,若标识符两侧运算符 *+=2 , 标识符是二维指针标识符是二维指针表达式表达式含义含义* *+指针级别指针级别c c二维数组首地址二维数组首地址0 0二级指针二级指针c+ic+i第第i行首地址行首地址0 0二级指针二级指针ci+jci+j第第i行行j列元素地址列元素地址1 1一级指针一级指针cijcij 第第i行行j列元素值列元素值2 2值值注意:以上总结仅限于标识符两侧仅有注意:以上总结仅限于标识符两侧仅有* *,两个运算符两个运算符指针变量小结指针变量小结二级指针二级指针(1)二级指针二级指针 int c310 ,*pc , *p;(2)(2)赋值赋值定义定义标识

55、符时,若标识符两侧运算符标识符时,若标识符两侧运算符 *+=2 , 标识符标识符c,pc是二维指针是二维指针注意:以上总结仅限于标识符两侧仅有注意:以上总结仅限于标识符两侧仅有* *,两个运算符两个运算符s s / pc / pc 指向指向c c数组数组 pc = c ; pc = c ;表达式表达式含义含义* *+指针级别指针级别pcpc二维数组首地址二维数组首地址0 0二级指针二级指针pc+ipc+i第第i行首地址行首地址0 0二级指针二级指针pci+jpci+j第第i行行j列元素地址列元素地址1 1一级指针一级指针pcijpcij 第第i行行j列元素值列元素值2 2值值p如何赋值8.4.

56、1 字符串的引用方式字符串的引用方式8.4.2 字符指针作函数参数字符指针作函数参数8.4.3 使用字符指针变量和字符数组的比较使用字符指针变量和字符数组的比较(1) 可以通过可以通过字符指针字符指针引用存放在引用存放在数组数组中的字符串。中的字符串。(2) 可以可以通过字符指通过字符指针针变量引用字符串常量。变量引用字符串常量。 例例8.16 定义一个字符数组,在其中存放字符串定义一个字符数组,在其中存放字符串“I love China!”,输出该字符串和第,输出该字符串和第8个字符。个字符。#include int main() char string=I love China!; pri

57、ntf(%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!”I love China!”的首地址赋给指针的首地址赋给指针变量变量stringstring例例8.18 将字符串将字符串a复制为字符串复制

58、为字符串b,然后输出字符串,然后输出字符串b。#include int main() char a =I am a student.,b20; int i; for(i=0;ai!=0;i+) bi=ai; bi=0; printf(string a is:%sn,a); printf(string b is:); for(i=0;bi!=0;i+) printf(%c,bi); printf(n); return 0; 例例8.18 将字符串将字符串a复制为字符串复制为字符串b,然后输出字符串,然后输出字符串b。#include int main() char a =I am a stude

59、nt.,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; 例例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; p

60、rintf(string a is:%sn,a); printf(string b is:%sn,b); return 0; 如果想把一个字符串从一个函数如果想把一个字符串从一个函数“传递传递”到另一个函数,可以到另一个函数,可以用用指针实现指针实现。 将一个字符串从一个函数传递到另一个函数,可以使用传地址将一个字符串从一个函数传递到另一个函数,可以使用传地址的方式,即用字符数组名或字符指针变量作参数。有以下四种的方式,即用字符数组名或字符指针变量作参数。有以下四种情况:情况: 实参实参 形参形参 1 1 数组名数组名 数组名数组名 2 2 数组名数组名 字符指针变量字符指针变量 3 3 字符

61、指针变量字符指针变量 字符指针变量字符指针变量 4 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;实参是数组名实参是数组名vo

温馨提示

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

评论

0/150

提交评论