已阅读5页,还剩156页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第十章 指针 重点: 指针的概念、指针的运算、指针的应用 难点: 指针概念的建立 2004年11月1日 10.1指针的概念 凡在程序中定义的变量,在编 译时,系统都给它们分配相应的 存储单元。如,一般微机C系统 给int 变量分配2字节,给float变 量分配4字节。每个变量所占用 的存储单元都有确定的地址,具 体的地址是在编译时分配的。例 如: int a = 3 , b = 4; float c = 4.5 , d=8.6 ; char e = w , f=y ; 它们在内存中的情况如右图所示 : 内存区的每个字节有一个 编号,这就是“地址”,它相当 于旅馆的房间号。在地址所 标志的单元中存放数据,相 当于房间中住旅客一样。 变量的地址是其所占存储 空间第一个字节的编号,是 用: 实际上,在编译时,在内存中不再出现变量, 而只有地址将键盘输入的一 个数存到1012开始的2个字节的整型存储单元中 。 这种按变量地址存取变量值的方式,称为“直 接存取”方式或称“直接访问”方式。 “间接存取间接存取”方式或称方式或称“间接访问间接访问”方式:先找方式:先找 到存放到存放a a的地址的变量的地址的变量papa,从中取出从中取出a a的地址,然的地址,然 后将后将3 3送到送到10101010开始的开始的2 2个字节的整型存储单元中个字节的整型存储单元中 a 1010 3 a 1010 3 1010 pa 直接将3送到整型变量a所标 识的单元中 将3送到指针变量pa所指向的单元 由于通过变量的地址能找到变量的存储单元 ,我们说地址“指向”该变量单元(如同房 间号指向某一房间一样)。 路牌路 变量地址变量内存单元 指向 指向 在三岔路口,路牌就是一个指针,它指向某一目的地 ; 变量的地址它指向变量的存储单元,因此变量的地址 就是变量的指针。若一个变量的地址为2000可以说变 量的指针为2000。 房间号房间 指向 下图:a的地址为1010,即1010指向a的存储单元。如同 房间号1010指向1010房间。 例如要想得到b的值,可以先访问变量pb,得到pb的值 1012,它是b的地址。再通过地址1012找到它所指向 的存储单元中的值 pb=称pa“指向”变量a,pa就是指向a的指针变 量。pa指向了a,就可以通过pa指针对a进行操作。 区别: 指针:即地址(变量的地址即变量的指针) 指针变量:其值为地址的变量 指向:是通过地址来体现,通过地址能找到所需 的变量单元,因此可说,地址指向该变量单元 。 char *p2; float *p3; 说明:(1) * 表示指向,说明p1、 p2、 p3为指针型变 量 (2) 指针变量有确定的指向的数据类型。 intint *p1*p1; ;中中intint是指:所定义的指针变量是指向整型数据的是指:所定义的指针变量是指向整型数据的 指针变量,或者说指针变量,或者说p1p1只能存放整型数据的地址,也就是说只能存放整型数据的地址,也就是说 p1p1只能用来指向整型数据;只能用来指向整型数据; intint 就是指针变量的就是指针变量的基类型基类型, 指针变量的基类型用来指定该指针变量可以指向的变量的指针变量的基类型用来指定该指针变量可以指向的变量的 类型。类型。 pa、pb等分别指向不同数据类型的指针变量,它们的共 同点:值为地址,且它们的存储单元空间是一样的。 ?一个指向char的指针和一个指向int的指向不同 点: 其实,指针本身只有一种,指针变量存放的值都 是内存地址。在定义指针时,定义指针所指向 的数据类型的目的是说明如何解释指针所指向 的空间的数据。 0x30 0x31 0x32 0x33 0x0 0x0065FDED 0x0065FDEE 0x0065FDEF 0x0065FDF0 0x0065FDF1 如果有一个整型指针*p指向了地址 0x0065FDED,那么系统就会将 指针指向的地址开始的2个字节当 成整数值来解释;而如果一个字符 指针*s指向了地址0x0065FDED, 那么系统会认为这里存放了一个字 符串。 在定义指针变量时要注意: 1 一般形式:基类型 *指针变量名 2 不能用一个整数给一个指针变量赋初值 int *p=2000; 写此语句的原意可能是想将地址2000作为指针变 量p的初值,但编译系统并不把2000认为是地址 ,而认为是整数,因此认为是语法错误。 3 在定义指针变量时必须指针基类型。 float *p;p+;说明p只能指向类型为实型的变量 ,且使指针移动1个位置意味着移动4个字节。 二、指针变量的引用 1 有两个与指针变量有关的运算符 float *pf= char ch; char *str= int t,k; int *p1= 错误着是: p1= pf= str= 2)同类型的指针变量之间可以互相赋值 int t1=1; int *p1,*p2; p1= p2=p1; 3)不同类型的指针变量之间可以通过类型强制转换互 相赋值 例10.1 #include void main() int a=2,*b,*k= float c=2.3,*d; b=(int *) d=(float *)k; printf(“%4d%4d%f”,*b,*k,*d); 4)可以将NULL(0)赋给指针变量,它表示指针变量 为空,即该指针变量不指向任何存储单元。 3、用指针变量对变量赋值 如: int i , j , *p; p= *p=3; j=*p+2; p= 的意义为指针变量p指向变量 i。 注意:p是地址变量, *p 是非地址变量,与i是一回事。 例10.2 main() int a,b; int *pointer_1,*pointer_2; a100;b=10; pointer_1 关于运算符 p1=p2= p=a=3; (*p)+; *p+; *(+p); 例10.3 输入a和b两个整数,按先大后小的顺序输出a和b 。 #include main() int *p1,*p2,*p,a,b; scanf(“d,d“, p1=a;p2=b; if(ab) p=p1;pl=p2;p2=p; printf(“na=d,b=d”,a,b); printf(“max=d,min=dn“,*pl,*p2); 交换地址(指针变量),使p1指向大数b,而变 量a、b未变。 p2=p; 三、指针变量作为函数参数 值传递方式:函数的形参为变量;实参可以是变 量、 常型、表达式。 地址传递方式:函数的形参可以是指针变量,实 参 可以为地址或同类型的指针变量。 功能:将一个变量的地址传送到另一函数中,实 参 和形参均可用指针。 例10.4 对输入的两个整数按大小顺序输出。今用函 数处理,而且用指针类型的数据作函数参数程序如下 : swap(p1,p2) int *p1,*p2; int p; p=*p1;*p1=*p2;*p2=p; main() int a,b; int *pointer_1, *pointer_2; scanf(“d,d”, pointer_1 if(ab) swap(pointer_1 ,pointer_2); printf(“nd,dn“a,b); 调用函数时可以改变实参 指针变量所指向变量的值。 例10.4 程序可修改为: swap(p1,p2) int *p1,*p2; int p; p=*p1;*p1=*p2;*p2=p; main() int a,b; scanf(“d,d”, if(ab) swap( p=*p1;*p1=*p2p=*p1;*p1=*p2;*p2=p;*p2=p; 下面例子不能正确交换数据: swap(pl,p2) int *p1,*p2; int *p; ppl;p1=p2;p2p; main() int a,b; int *pointer_1,*pointer_2; scanf(“dd”, 出错的原因是参量不是双向传递。 p=*pt1; *ptl=*pt2;*pt2=p; exchange (q1,q2,q3) int *q1,*q2,*q3; if(*ql main() static int i,a10=0,1,2,3,4,5,6,7,8,9; printf(“the orginal array:n“); for(i=0;i main() static int i,a10=0,1,2,3,4,5,6,7,8,9; int *p=a; printf(“the orginal array:n“); for(i=0;imax) max=*p; else if(*pmax) max=*p; else if(*p void main() int a34=1,2,3,4,5,6,7,8,9,10,11,12; int *p; for (p=a0;pb) x=a; else x=b; return x; main( ) int x,y; int (*p)( ); p=max;/*p为指向函数max的指针变量*/ scanf(“%d%d”, printf(“%dn”,(*p)(x,y); 二、用指向函数的指针变量作函数的参数 传递的是函数的入口地址, 一般的使用形式: : sub( f1, f2); /* 主调函数/* : sub(x1, x2) int (*x1)( ), (*x2)( ); int a,b,i,j; : /* 次主调函数*/ a=(*x1)(i); /*x1、*x2为被调函数 */ b=(*x2)(i,j); : f1 x1 f1 f2 x2 f2 例10.23 设一个函数process,在调用它时,每次实现不同的功 能,调用三次,分别求出a、b中较大者、较小者和二者之和 。 main() int max(_),min(_),add(_); int a,b; printf(“Enter a and b:“); scanf(“%d,%d“, printf(“max=“); process(a,b,max); /*主调函数的实参用函数名*/ printf(“min=“); process(a,b,min); /*一般在嵌套调用中使用*/ printf(“sum=“); process(a,b,add); /*次主调函数对其它函数操作,完成一定的功能;*/ printf(“n“); max(x,y) int x,y; int z; return(z=xy?x:y); min(x,y) int x,y; int z; return(z=x main() static float score4=60,70,80,90, 56,89,67,88,34,78,90,66; float *search(); float *p; int i,m; printf(“enter the number of student:“); scanf(“%d“, printf(“the scores of No.%d are:n“,m+1); p=search(score,m); for(i=0;i int k=0; int *fun1() return int *fun2(int *ptr) return ptr; main() *fun1()=10; printf(“k=%dn”,k); int t=3; *fun2( printf (“t=%dn”,t); 10. 7 指针数组和指向指针的指针 重点:指针数组及其应用 一、指针数组 其元素均为指针型数据的数组,称为指针数组。 定义形式: 类型标识符 *数组名数组长度说明 如: int *p4; 不能写成 int (*p)4 注意: 1) 在使用指针数组中的元素之前,必须为该元素指定 一个确定的值;对指针数组的初始化时其每个元素 的值都为地址。 int i1,i2,i3; int *p3= char *str3=“Guangzhou”,”Biejing”,”Wuhan”; 2) 在使用指针数组元素时,与指针的使用方法一样 #include main() int k4,t; int *p4= for (t=0;t0) k=j; if(k!=i) temp=namei;namei=namek;namek=temp; void print(name,n) char *name;int n; int i; for(i=0;icopy file1.c file2.c 这个命令中, copy是程序名, file1.c和file2.c是命令 行参数,启动程序所给的命令信息将通过操作系统 传递给程序的main函数,传递的方式是:将命令行 将空格分解成一个个字符串,然后将字符串组织到 一个字符数组中,并且将这个数组连同数组中字符 串的个数值都传递给main函数。 使用一般形式: 文件名 参数1 参数2 参数n (2) 形参的意义 argc : 参数的数目,为整型, int argc 如: file1 China Beijing 为三个参数,传过来后使 argc得到3。 argv : 是字符数组名,其元素得到的是命令行各 字符串的首地址, 定义形式为: char *argv 数组长度由命令行各字符串的个数 确定; 如: file1 China Beijing 使argv 的长度为3,argv0指向file1,argv1指向 China, argv2指向Beijing。 3 main函数带参数的例子 考察参数回送命令echo的内容,文件名为 echo.c main(argc,argv) int argc; char *argv ; char *p=argv; while(-argc0) printf(“%s%c”,*+p, (argc1)? : n); 运行,若输入: echo Computer and C Language 回车 则显示: Computer and C Language 10.8 指针型数据小结 一、有关指针的数据类型(见下表) 二、指针运算小结 1、指针变量加减一个整数 如:p+ p- p+i p-i p+=i p-=i 等 实际含义:如 p+i 代表地址计算: p+c*i , c为字节数,整型c=2、实型c=4、字符型 c=1 作用:p是作为指向数组元素的指针变量时 才有使用意义 2、指针变量赋值 如: p= int *k=(int *)p; 本章练习 一、填空题 1 专门用来存放某种类型变量的首地址的变量被称为该 种类型的_,它的值类型是_. 2 数组的指针是指数组的_,而数组中某个元素 的指针就是_.指针变量内存放的是数组 的首地址,则它被称为_. 3 指向字符串的指针变量的类型是_,不过它 保存的是字符串的_,或者是_. 4 每一个函数都占用一段内存,在编译时被分配一个_ _,这个是函数的指针,可以让一个指针变 量指向函数,然后就可以通过调用这个指针变量来调 用函数。 5 在带参数的main函数中,main(参数1,参数2),参数1 和参数2就是main的形参,其中参数1是_, 参数2是一个指向字符串的_. 6 如果引用数组元素,可以有两种方法:_,_。 7 在C语言中,实现一个字符串的方法有两种,用_ _实现和用_实现。 以下程序用指针指向三个整型存储单元,输入三个整 数,并保持这三个存储单元中的值不变,选出其中最 小值并输出。 #include main( ) int _; a=(int *)malloc(sizeof(int); b=(int *)malloc(sizeof(int); c=(int *)malloc(sizeof(int); min=(int *)malloc(sizeof(int); printf(“输入三个整数n”); scanf(“%d%d%d”,_); printf(“输出以上整数:%d%d%dn”,_); *min=*a; if(*min*b) _; if(_*c) _; printf(“输出最小的整数:%d”,_); 9 阅读下面的程序,若要得到如下的运行结果: Follow me Basic Fortran Great Wall Computer design 请将程序补充完整 main( ) static char *name=“Follow me”, “Basic”, “Fortran”, “Great Wall”, “Computer design”; char *ip; int t; for (t=0;t #include main( ) char *s1=“AbDeG”; char *s2=“AbdEg”; s1+=2;s2+=2; printf(“%dn”,strcmp(s1,s2); 正数 负数 零 不确定的值 10. 当运行以下程序时,从键盘输入MyBooK回车 ,则下面程序的运行结果是_。 #include char fun(char *s) if (*s=A) *s+=32; return *s; main( ) char c80,*p; p=c; scanf(“%s”,p); while(*p) *p=fun(p);putchar(*p);p+; printf(“n”); A) mY bOOK B) my book C) my D) My Book 11. 下面程序的运行结果是_ #include #include fun(char *s) char a7; s=a; strcpy(a,”look”); main() char *p; fun(p); puts(p); A) look B) look C) look D) 不确定的值 表示空格 12.若有定义:int a23;则对a数组的第I行j列元 素值的正确引用是_ A) *(*(a+i)+j) (a+i)j *(a+i+j) D) *(a+i)+j 13 以下程序的输出结果是_ char cchar(char ch) if (ch=A if (*p1*p2) p=*p1;*p1=*p2;*p2=p; main() int a,b,c; scanf(“%d%d%d“, printf(“n%4d%4d%4dn“,a,b,c); if(ab) sort( if(ac) sort( if(bc) sort( printf(“%4d%4d%4dn“,a,b,c); 10.2 输入三个字符串, 按由小到大的顺序输出 str0第一个字符串 “china” str1第二个字符串 “beijing” str2第三个字符串 “123” 解题思路: 假设str为指针数组,其中三个元素分别指向三个字符串 str0第一个字符串 “china” str1第二个字符串 “beijing” str2第三个字符串 “123” 要实现从小到大的顺序输出,可通过改变数组元素 的指向即可 所有语句皆放在主函数函数体内 #include #include main() char string320; char *str3=string0,string1,string2; char *p; int t; for (t=0;t0) p=str0;str0=str1;str1=p; if(strcmp(str0,str2)0) p=str0;str0=str2;str2=p; if(strcmp(str1,str2)0) p=str1;str1=str2;str2=p; for (t=0;t #include sort(char *p1,char *p2) char p20; strcpy(p,p1); strcpy(p1,p2); strcpy(p2,p); main() char string320; char *str3=string0,string1,string2; char *p;int t; for (t=0;t0) sort(str0,str1); if(strcmp(str0,str2)0) sort(str0,str2); if(strcmp(str1,str2)0) sort(str1,str2); for (t=0;tmax) max=*(a+i); if(*(a+i) #define N 10 void sort(int *t,int m) int k,i; for (k=0;k #define N 100 int str_long(char *p) int i=0; while(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 房屋置换物品协议书
- 房屋订购协议书范本
- 房屋质量包赔协议书
- 房租归集协议书范本
- 房租装修安全协议书
- 手工活外发协议合同
- 手机售后免责协议书
- 手游公司合作协议书
- 手机领取协议书范本
- 打印工程纸合同范本
- 交通管理扣留车辆拖移、保管项目 投标方案(技术标)
- 气相色谱-质谱联用法测定鱼腥草挥发油中4种成分的含量
- 国际贸易理论与实务(英文版)PPT完整全套教学课件
- 故意杀人上诉状范文两篇
- 小工具批量处理邻区脚本实用操作
- 三年级科学下册《谁在水中溶解得多》实验报告单
- 10KV开关柜验收报告
- 高中数学 数列 4.4数学归纳法第1课时
- GB/T 7735-2004钢管涡流探伤检验方法
- GB/T 21566-2008危险品爆炸品摩擦感度试验方法
- 医学导论-课件
评论
0/150
提交评论