C语言指针(含例子)ppt课件_第1页
C语言指针(含例子)ppt课件_第2页
C语言指针(含例子)ppt课件_第3页
C语言指针(含例子)ppt课件_第4页
C语言指针(含例子)ppt课件_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

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

文档简介

1、.,C语言程序设计大赛培训之 指针,教学实践部计算机中心 胡晓丽,.,指针的用途,指针在C 语言里应用极为广泛,是C语言的灵魂 使程序简洁、紧凑、高效 函数调用时批量参数的传递 内存的动态分配 内存地址的直接处理 复杂数据结构的简洁表达等许多其它数据类型难以实现的复杂操作,.,培训目的,掌握指针的概念、指针变量定义格式和引用 掌握指针的运算方法 指针应用举例,.,理解指针,指针 就是内存中的变量的地址,.,理解指针,内存单元的编号:计算机内存中,每一个字节的存储单元都有一个编号(亦称为内存地址) 在VC中,内存单元的编号是一个8位的十六进制数(表示32位二进制数,VC是32位编译系统) 如:0

2、013FF7C,.,理解指针,变量:实质是代表了“内存中的某个存储单元”。,若在内存中定义了一个变量,则这个变量的内存的地址也就确定了。,.,理解指针,变量的地址:表示变量在内存中的位置,其值是该变量在内存中所占存储单元的首字节的编号,.,程序中: int i; float k;,内存中每个字节有一个编号-地址,i,k,编译或函数调用时为其分配内存单元,变量是对程序中数据 存储空间的抽象,理解指针,.,a在内存中占4个字节,但 a=8; printf(%d %pn,a, ,理解指针,.,理解指针,我们在程序中只需要指出变量名,无需知道每个变量 在内存中的具体地址,每个变量与具体地址的联系是 由

3、C编译系统来完成的。对变量的存取操作就是对某 个存储单元进行操作。这种直接按变量的地址存取变 量值的方式称为“直接存取”。,.,4502,实 验 室 二,我有几种方法可以到实验室上机?,2、按实验室所在的 教室编号,1、按实验室名字,按变量名,按变量地址 (即 指针),实 验 室 一,实 验 室 三,4503,4707,理解指针,.,理解指针,指针:也是一种变量,这种变量是用来存放内存地址的。,.,指针变量,指针是 字节的编号,即地址。 指针也是要存储的,因此每个指针也需要一个变量来存储它。这个变量称为指针变量。指针变量的值是某一定义好的变量的地址。,.,理解指针变量, int a=3;,10

4、12,2002,间接存取:这种通过变量p到变量a的地址,然后再存取变量a的值的方式称为“间接存取”。,指针变量p指向了变量a的含义是:指针p中存放了变量a的地址。,.,指针变量的定义,定义形式如下: 数据类型 *指针变量名; 如: int *p1, num; 表示的意思为: 定义了一个指针变量p1,它指向的是一个整型数据。或者说,这时候p1中存储的是一个整型变量的地址。 注意:指针变量定义了之后,需要给它赋一个确定的变量的地址,否则,就会出现严重的系统错误。,.,指针变量的引用,#include ,main() ,int a; /定义一个整型变量a,int *p1; /定义指向整型变量的指针p

5、1,p1= /p1中应存放变量a的地址,*p1=5; /通过指针变量p1给a赋值,printf(a=%d, a);,.,例:int *p,*s,k=20; s=,20,2000,2000,2004,2004,s=*p k=*s 所以:k=*p,说明: (1)指针p的基类型是int类型的指针。 (2)是求地址运算符。 (3)因为基本数据类型int、float、char等所需存储空间不同,所以需要定义指针变量的基类型。,.,例: 指针的概念,main() int a; int *pa= ,运行结果: a:10 *pa:10 ,DD04,q+;,DD06,q-;,DD04,i=*p;,11,j=*q

6、;,33,例:,.,指针的运算方法,指针的比较,在关系表达式中,可以对指针进行比较。即两个变量地址的比较。,通常两个或多个指针指向同一目标时(一串连续的存储单元),比较才有意义。,.,指针应用举例-指针作为函数的参数,指针可以作为参数在主调函数和被调用函数之间 传递数据,通过指针可以在被调用函数中地调用 中的变量进行引用,这也就使得通过形参改变对 应实参的值有了可能,利用此形式就可以把两个 或两个以上的数据从被调用的函数返回到调用函数。,.,例 将数从大到小输出,指针应用举例-指针作为函数的参数,swap(int x,int y) int temp; temp=x; x=y; y=temp;

7、main() int a,b; scanf(%d,%d, ,.,指针应用举例-指针作为函数的参数,5,9,5,5,9,COPY,swap(int x,int y) int temp; temp=x; x=y; y=temp; main() int a,b; scanf(%d,%d, ,.,指针应用举例-指针作为函数的参数,swap(int x,int y) int temp; temp=x; x=y; y=temp; main() int a,b; scanf(%d,%d, ,值传递,运行结果:5, 9,(swap),5,9,5,9,5,.,swap(int *p1, int *p2) int

8、 p; p=*p1; *p1=*p2; *p2=p; main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d, ,5,9,2000,2002,5,9,COPY,5,运行结果:9,5,地址传递,通过传送地址值,可以在被调用函数中直接改变调用函数中的变量的值,指针应用举例-指针作为函数的参数,.,指针应用举例-指向数组的指针变量,例编写程序,定义一个含有15个元素的数组,并编写函数分别完成以下操作: (1)调用C库函数中的随机函数给所有元素赋以049之间的随机数; (2)输出数组元素中的值; (3)按顺序对每隔三个数求一个和数,并传回主函数;

9、(4)最后输出所有求出的和值。,.,指针应用举例-指向数组的指针变量,调用随机函数的方法如下:包含头文件stdlib.h n=rand()%x; n将得到一个在0(x-1)之间的随机数。,.,指针应用举例-指向数组的指针变量,分析: (1)由于要每隔3个数求一个和,15个数要求出5个和,所以主函数中要定义一个数组来存放5个和数。 (2)两次输出元素的值,虽然输出对象不同,但是数组的类型相同,可调用一个函数来完成,只要指定不同的数组名,不同的输出个数即可。,.,指针应用举例-指向数组的指针变量,#include stdio.h #include stdlib.h #define SIZE 15

10、#define N 3 void getrand(int *,int); void getave(int *,int *,int); void printarr(int *,int);,.,指针应用举例-指向数组的指针变量,void printarr(int *a,int n) int i; for(i=0;in;i+) printf(%4d, *(a+i); if(i+1)%5=0) printf(n); printf(n); ,.,指针应用举例-指向数组的指针变量,void getave(int *a,int *b,int n) int i,j=0,sum=0; for(i=0;in;i+

11、) sum+=*(a+i);/*累加数组元素*/ if(i+1)%3=0) /*每累加3个进行一次处理*/bj=sum;sum=0;j+; ,.,指针应用举例-指向数组的指针变量,void getrand(int *a,int n) int i; for(i=0;in;i+) *(a+i)=rand()%50; ,.,指针应用举例-指向数组的指针变量,main() int xSIZE,wSIZE/N=0; /*数组中置初值为0,准备存放5个数的和*/ clrscr(); getrand(x,SIZE); /*调用函数产生15个随机数放入数组x中*/ printf(nOutput %d rand

12、om numbers:n ,SIZE); printarr(x,SIZE); /*输出15个随机数*/ getave(x,w,SIZE); /*每3个数求一个和放入数组w中*/ printf(nOutput 5 sum numbers:n); printarr(w,SIZE/N); /*输出5个数的和*/ ,.,指针应用举例-指向数组的指针变量,.,指针应用举例-指向数组的指针变量,例:编写程序,将数组中的数按颠倒的顺序重新存放。在操作时,只能借助一个临时存储单元而不得另外开辟数组。,分析:不是要求按颠倒的顺序打印数据,而是要求按逆序重新放置数组中的内容。假定a数组中有8个元素,.,指针应用举

13、例-指向数组的指针变量,.,指针应用举例-指向数组的指针变量,(1)定义两个变量i和j,首先将a0,a7进行对调,中间用到一个临时存储单元,所以定义同类型变量temp。 (2)将变量i加1,j减1,满足条件ij时,将a1和a6进行对调 (3)最后将a3和a4进行对调,此时i+1,j-1不再满足条件ij,.,指针应用举例-指向数组的指针变量,#include stdio.h #define NUM 8 void invert(int *,int); void priout(int *,int);,main() int aNUM=10,20,30,40,50,60,70,80; printf(nO

14、utput primary data: ); priout(a,NUM); invert(a,NUM); printf(nOutput the inverse data: ); priout(a,NUM); ,.,指针应用举例-指向数组的指针变量,void priout(int s,int n) int i; for(i=0;in;i+) printf(%4d,si); printf(n); ,void invert(int *a,int n) int i,j,temp; for(i=0,j=n-1;ij;i+,j-) temp=*(a+i); *(a+i)=*(a+j); *(a+j)=te

15、mp; ,.,指针应用举例-指向数组的指针变量,例:w数组中存放了n个数据,编写函数删除下标为k 的元素的值。,.,指针应用举例-指向数组的指针变量,k,26,27,28,29,30,.,指针应用举例-指向数组的指针变量,getindex:用于输入所删除元素的下标,函数中对输入的下标进行检查,若越界,则要求重新输入,直到正确为止。 arrout:用于输出数组中的元素 arrdel:进行所要求的删除操作,.,指针应用举例-指向数组的指针变量,#include stdio.h #define NUM 10 int arrdel(int *,int,int); void arrout(int *,i

16、nt); int getindex(int n);,.,指针应用举例-指向数组的指针变量,main() int n,d,aNUM=21,22,23,24,25,26,27,28,29,30; n=NUM; printf(Output primary data: n); arrout(a,n); d=getindex(n); n=arrdel(a,n,d); printf(nOutput the data after delete:n); arrout(a,n); ,.,指针应用举例-指向数组的指针变量,getindex(int n) int p; do printf(nEnter the in

17、dex 0n-1); return p; ,void arrout(int w,int m) int k; for(k=0;km;k+) printf(%5d,wk); printf(n); ,.,指针应用举例-指向数组的指针变量,int arrdel(int *a,int n,int k) int i; for(i=k;in-1;i+) ai=ai+1; n-; return n; ,.,指针应用举例-指针指向字符串,例:编写函数strlength(*s),函数返回指针s所指字符串的长度。 相当于库函数strlen的功能。,.,指针应用举例-指针指向字符串,#include stdio.h

18、#include string.h int strlength(char *s) int n=0; while(*(s+n)!=0) n+; return n; ,main() char str=ABCDEF; int len1,len2; len1=strlength(); len2=strlength(str); printf(len1=%d,len2=%d,len1,len2); ,.,指针应用举例-指针指向字符串,例:编写程序从若干字符串中找出最小的串进行输出。,#include stdio.h #include string.h #define N 20 #define M 81,.

19、,指针应用举例-指针指向字符串,int getstr(char pM) char tM;/*开辟一个临时的字符串存储空间*/ int n=0; printf(Enter string. a empty string to end.n); gets(t); while(strcmp(t,) strcpy(pn,t);n+; gets(t); return n; ,.,指针应用举例-指针指向字符串,char *findmin(char (*a)M,int n) char *q; int i; q=a0;/*用q指向字符串数组中最小串的地址*/ for(i=0;i0) q=ai; return q;

20、 ,.,指针应用举例-指针指向字符串,main() char sNM,*sp; int n; n=getstr(s); sp=findmin(s,n); puts(sp); ,.,指针应用举例-函数指针,指向函数的指针变量的定义,#include “stdio.h” double fun(int a,int *p) main() double (*fp)(int ,int *),y; int n; fp=fun; y=(*fp)(56,double tran(double (*f1)(double),double (*f2)(double),double x) return (*f1)(x)/

21、(*f2)(x); ,.,指针应用举例-函数指针,main() double y,v; v=60*3.1416/180.0; /*v=600*/ y=tran(sin,cos,v); printf(“tan(60)=%10.6fn”,y); y=tran(cos,sin,v); printf(“cos(60)=%10.6fn”,y); ,.,指针应用举例-动态存储分配,例: short int *pi; float *pf; pi=(short *)malloc(2); pf=(float *)malloc(4);,说明: (1)因为malloc是void型的,所以需要强制转换类型 (2)强制

22、转换类型括号中的不可少,否则就变成了普通类型。,if(pi!=NULL) *p=6; if(pf!=NULL) *pf=3.8,.,指针应用举例-动态存储分配,注意: 由动态存储分配得到的存储单元没有名字,只能靠指针来引用它。一旦指针改变指向,则原存储单元及所存数据都将无法引用。 通过调用malloc函数所分配的单元动态存储单元中没有确定的初值。 在动态申请存储空间时,若不能确定数据类型所占字节数,可通过sizeof运算符来求得。,.,指针应用举例-动态存储分配,例: pi=(int *)malloc(sizeof(int); pf=(float *)malloc(sizeof(float);

23、 由系统来计算指定类型所占的字节数,有利于程序 的移植。,.,指针应用举例-链表,单链表,struct slist int data; struct slist *next; ; typedef struct slist SLIST;,head,.,指针应用举例-链表,(1)建立带有头结点的单向链表 步骤: 读取数据 生成新结点 将数据存入结点的成员变量中 将新结点插入到链表中。 (重复操作直到输入结束)。,.,指针应用举例-链表,例:编写函数creat_slist,建立如上图所求的单向链表。结点数据域的内容从键盘输入,以-1作为输入结束标志。链表头结点的地址由函数值返回。,h:头指针,存放头

24、结点的地址 r:指向链表当前的尾结点 s:指向新生成的结点 每当s把新开辟的结点链接到链表尾后,r便移向这一新的表尾结点。,.,#include stdio.h #include stdlib.h struct node int data; struct node *next; ; typedef struct node SLIST;,main() SLIST *head; . head=return creat_slist(); /*调用链表建立函数,得到头结点地址*/ ,SLIST *creat_slist() SLIST *h,*s,*r; int c; h=(SLIST*)malloc(sizeof(SLIST);/*生成头结点*/ r=h; scanf(%d, ,head,h-next=0,指针应用举例-链表,.,(1)顺序访问链表中各结点的

温馨提示

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

评论

0/150

提交评论