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

下载本文档

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

文档简介

1、C语言程序设计大赛培训之 指针教学实践部计算机中心教学实践部计算机中心胡晓丽胡晓丽指针的用途指针在指针在C 语言里应用极为广泛,是语言里应用极为广泛,是C语言的灵魂语言的灵魂等许多其它数据类型等许多其它数据类型难以实现的复杂操作难以实现的复杂操作培训目的o掌握指针的概念、指针变量定义格式和引用o掌握指针的运算方法o指针应用举例理解指针理解指针 指针指针 就是内存中的就是内存中的变量的地址变量的地址理解指针理解指针o内存单元的编号:计算机内内存单元的编号:计算机内存中,每一个字节的存储单存中,每一个字节的存储单元都有一个编号(亦称为元都有一个编号(亦称为内内存地址存地址) o在在VC中,内存单元

2、的编号是中,内存单元的编号是一个一个8位的十六进制数(表示位的十六进制数(表示32位二进制数,位二进制数,VC是是32位编位编译系统)译系统) 如:如:0013FF7C0013FF7C0013FF7B0013FF7A0013FF790013FF00.理解指针变量变量:实质是代表了“内存中的某个存储单元”。若在内存中定义了一个变量,则这个变量的内存的地址也就确定了。若在内存中定义了一个变量,则这个变量的内存的地址也就确定了。理解指针变量的地址变量的地址:表示变量在内存中的位置,其:表示变量在内存中的位置,其值是该变量在内存中所占存储单元的首字节的编值是该变量在内存中所占存储单元的首字节的编号号

3、程序中: int i; float k; 内存中每个字节有一个编号-地址.2000200120022005内存02003ik 编译或函数调用时为其分配内存单元变量是对程序中数据存储空间的抽象理解指针oa在内存中占在内存中占4个字节,但个字节,但&a的值是的值是4个字节中首个字节的编号个字节中首个字节的编号 n运算符运算符&:取地址,如:取地址,如&a 的值为变量的值为变量a的地址的地址 n变量地址的输出可以用格式字符串变量地址的输出可以用格式字符串“%p”#include void main() int a;a=8;printf(%d %pn,a,&a); 0013FF7C0000000000

4、13FF7B000000000013FF7A000000000013FF79000010000013FF00.理解指针理解指针我们在程序中只需要指出变量名,无需知道每个变量我们在程序中只需要指出变量名,无需知道每个变量在内存中的具体地址,每个变量与具体地址的联系是在内存中的具体地址,每个变量与具体地址的联系是由由C编译系统来完成的。对变量的存取操作就是对某编译系统来完成的。对变量的存取操作就是对某个存储单元进行操作。这种个存储单元进行操作。这种直接按变量的地址存取变直接按变量的地址存取变量值量值的方式称为的方式称为“直接存取直接存取”。 4502实实验验室室二二我有几种方法我有几种方法可以到实

5、验室可以到实验室上机?上机?2、按实验室所在的、按实验室所在的教室编号教室编号1、按实验室名字、按实验室名字按变量名按变量名按变量地址按变量地址 (即即 指针指针)实实验验室室一一实实验验室室三三45034707理解指针理解指针指针指针:也是一种变量,这种变量是用来存放内也是一种变量,这种变量是用来存放内存地址的。存地址的。指针变量o指针是指针是 字节的编号,即地址。字节的编号,即地址。 o指针也是要存储的,因此每个指针也需要指针也是要存储的,因此每个指针也需要一个变量来存储它。这个变量称为指针变一个变量来存储它。这个变量称为指针变量。指针变量的值是某一定义好的变量的量。指针变量的值是某一定义

6、好的变量的地址。地址。理解指针变量&a2001p=&a;1011ap例:例:int *p; int a=3;101220020000001100000000间接存取:这种通过变量p到变量a的地址,然后再存取变量a的值的方式称为“间接存取”。指针变量p指向了变量a的含义是:指针p中存放了变量a的地址。指针变量的定义定义形式如下:定义形式如下: 数据类型数据类型 *指针变量名指针变量名; 如:如: int *p1, num; o表示的意思为:表示的意思为: 定义了一个指针变量定义了一个指针变量p1,它指向的是一个整型数,它指向的是一个整型数据。或者说,这时候据。或者说,这时候p1中存储的是一个整型

7、变量中存储的是一个整型变量的地址。的地址。 o注意:指针变量定义了之后,需要给它赋一个确注意:指针变量定义了之后,需要给它赋一个确定的变量的地址,否则,就会出现严重的系统错定的变量的地址,否则,就会出现严重的系统错误。误。指针变量的引用#include main() int a; /定义一个整型变量定义一个整型变量a int *p1; /定义指向整型变量的指针定义指向整型变量的指针p1 p1=&a; /p1中应存放变量中应存放变量a的地址的地址 *p1=5; /通过指针变量通过指针变量p1给给a赋值赋值 printf(a=%d, a); 例:int *p,*s,k=20; s=&k; p=&s

8、;.2000200420062005整型变量k变量s200120022003变量p20072008202000200020042004s=*pk=*s所以:k=*p说明:(1)指针p的基类型是int类型的指针。(2)是求地址运算符。(3)因为基本数据类型int、float、char等所需存储空间不同,所以需要定义指针变量的基类型。例例: 指针的概念指针的概念main() int a; int *pa=&a; a=10; printf(a:%dn,a); printf(*pa:%dn,*pa); printf(&a:%x(hex)n,&a); printf(pa:%x(hex)n,pa); pr

9、intf(&pa:%x(hex)n,&pa);运行结果:a:10*pa:10&a:f86(hex)pa:f86(hex)&pa:f88(hex).f86f8af8cf8b整型变量a10指针变量paf87f88f89f86指针的运算方法指针的移动所谓移动指针就是对指针变量加上或减去一个所谓移动指针就是对指针变量加上或减去一个整数整数,或通过赋值运算,使指针指向相邻的存,或通过赋值运算,使指针指向相邻的存储单元。只有当指针指向一串连续的存储单元储单元。只有当指针指向一串连续的存储单元时,还可以和指向同一串连续存储单元的指针时,还可以和指向同一串连续存储单元的指针进行相减的运算,除此之外,不可以对指

10、针进进行相减的运算,除此之外,不可以对指针进行任何其它的算术运算。行任何其它的算术运算。指针的运算方法 指针变量只能进行逻辑运算和相减的算术运算。指针变量只能进行逻辑运算和相减的算术运算。 不是指向同一数组的指针变量运算是无意义的。不是指向同一数组的指针变量运算是无意义的。 指针变量的值加指针变量的值加1或减或减1,并不是地址加,并不是地址加1中减中减1,而是加,而是加上或减去该变量在内存中所占的字节数,该字节数由指上或减去该变量在内存中所占的字节数,该字节数由指针的基类型决定。针的基类型决定。指针的移动111122334455a0a1a2a3a4pqDD00DD02DD04DD06DD08D

11、D0ADD0CDD0EDD10ijDD12DD14DD16p=&a0;DD00q=p+2;DD04q+;DD06q-;DD04i=*p;11j=*q;33例:例:指针的运算方法指针的比较在关系表达式中,可以对指针进行比较。即两在关系表达式中,可以对指针进行比较。即两个变量地址的比较。个变量地址的比较。通常两个或多个指针指向同一目标时(一串连续的存储单元),比较才有意义。指针应用举例-指针作为函数的参数指针可以作为参数在主调函数和被调用函数之间指针可以作为参数在主调函数和被调用函数之间传递数据,通过指针可以在被调用函数中地调用传递数据,通过指针可以在被调用函数中地调用中的变量进行引用,这也就使得

12、通过形参改变对中的变量进行引用,这也就使得通过形参改变对应实参的值有了可能,利用此形式就可以把两个应实参的值有了可能,利用此形式就可以把两个或两个以上的数据从被调用的函数返回到调用函数。或两个以上的数据从被调用的函数返回到调用函数。例例 将数从大到小输出将数从大到小输出指针应用举例-指针作为函数的参数swap(int x,int y) int temp; temp=x; x=y; y=temp;main() int a,b; scanf(%d,%d,&a,&b); if(ab) swap(a,b); printf(n%d,%dn,a,b);指针应用举例-指针作为函数的参数.2000200820

13、0A2002200420065变量a 变量b(main)9 变量temp 变量y 变量x(swap)559 59COPYswap(int x,int y) int temp; temp=x; x=y; y=temp;main() int a,b; scanf(%d,%d,&a,&b); if(ab) swap(a,b); printf(n%d,%dn,a,b);指针应用举例-指针作为函数的参数swap(int x,int y) int temp; temp=x; x=y; y=temp;main() int a,b; scanf(%d,%d,&a,&b); if(ab) swap(a,b);

14、printf(n%d,%dn,a,b);值传递.20002008200A2002200420065变量a 变量b(main)9运行结果:5, 9变量x 变量y(swap) 变量t59595swap(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d,&a,&b); pointer_1=&a; pointer_2=&b; if(ab)swap(pointer_1,pointer_2); printf(n%d,%dn,a,b);.200020082

15、00A200220042006200C200E2010.59整型变量a 整型变量b(main)指针pointer_1指针pointer_220002002(swap)指针p1指针p2整型p5920002002COPY5运行结果:9,5地址传递通过传送地址值,可以在被调用函数中直接改变调用函数中的变量的值通过传送地址值,可以在被调用函数中直接改变调用函数中的变量的值指针应用举例-指针作为函数的参数指针应用举例-指向数组的指针变量例编写程序,定义一个含有15个元素的数组,并编写函数分别完成以下操作:(1)调用C库函数中的随机函数给所有元素赋以049之间的随机数;(2)输出数组元素中的值;(3)按顺

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

17、5#define N 3void 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+)sum+=*(a+i);/*累加

18、数组元素累加数组元素*/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(nOut

19、put %d random numbers:n ,SIZE);printarr(x,SIZE); /*输出输出15个随机数个随机数*/getave(x,w,SIZE); /*每每3个数求一个和放入数组个数求一个和放入数组w中中*/printf(nOutput 5 sum numbers:n);printarr(w,SIZE/N); /*输出输出5个数的和个数的和*/指针应用举例-指向数组的指针变量指针应用举例-指向数组的指针变量例:编写程序,将数组中的数按颠倒的顺序重例:编写程序,将数组中的数按颠倒的顺序重新存放。在操作时,只能借助一个临时存储单新存放。在操作时,只能借助一个临时存储单元而不得

20、另外开辟数组。元而不得另外开辟数组。分析:不是要求按颠倒的顺序打印数据,而是要分析:不是要求按颠倒的顺序打印数据,而是要求按逆序重新放置数组中的内容。假定求按逆序重新放置数组中的内容。假定a数组中数组中有有8个元素个元素指针应用举例-指向数组的指针变量102030405060708010011003100510071009100B100D100Fa0a1a2a3a4a5a6a7807060504030201010011003100510071009100B100D100Fa0a1a2a3a4a5a6a7指针应用举例-指向数组的指针变量(1)定义两个变量i和j,首先将a0,a7进行对调,中间用到

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

22、rse 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)=temp;指针应用举例-指向数组的指针变量例:例:w数组中存放了数组中存放了n个数据,编写函数删除下标为个数据,编写函数删除下标为k的元素的值。的元素的值。指针应用举例-指向数组的指针变量2

23、122232425262728293010011003100510071009a0a1a2a3a4a5a6a7a8a9k262728293021222324262728293030*10011003100510071009a0a1a2a3a4a5a6a7a8a9指针应用举例-指向数组的指针变量getindex:用于输入所删除元素的下标,函数中对输入的下标进行检查,若越界,则要求重新输入,直到正确为止。arrout:用于输出数组中的元素arrdel:进行所要求的删除操作指针应用举例-指向数组的指针变量#include stdio.h#define NUM 10int arrdel(int *,i

24、nt,int);void arrout(int *,int);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;doprintf(nEnter

25、the index 0=p%d:,n);scanf(%d,&p);while(pn-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所所指字符串的长度。指字符串的长度。相当于库函数相当于库函数strle

26、n的功能。的功能。指针应用举例-指针指向字符串#include stdio.h#include string.hint 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#

27、include string.h#define N 20#define M 81指针应用举例-指针指向字符串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指向字符串数

28、组中最小串的地址指向字符串数组中最小串的地址*/for(i=0;i0)q=ai;return q;指针应用举例-指针指向字符串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,&n)说明:(1)函数名代表该函数的入口地址(2)(*fp)(int,int *)说明fp是一个指向函数的

29、指针,这个函数的基类型是double(3)fp=fun把fun函数的地址赋给指针变量fp(4)y=(*fp)(56,&n)实现对该函数的调用。等于于 y=fun(56,&n)指针应用举例-函数指针例:函数名或指向函数的例:函数名或指向函数的指针作为实参指针作为实参#include #include double tran(double (*)(double),double (*)(double),double);double tran(double (*f1)(double),double (*f2)(double),double x)return (*f1)(x)/(*f2)(x);指针应用

30、举例-函数指针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)强制转换类型括号中的不可少,否则就变成了普通类型。if(pi!=NULL)

31、*p=6;if(pf!=NULL) *pf=3.863.8pipf指针应用举例-动态存储分配注意:由动态存储分配得到的存储单元没有名字,只能靠指针来引用它。一旦指针改变指向,则原存储单元及所存数据都将无法引用。通过调用malloc函数所分配的单元动态存储单元中没有确定的初值。在动态申请存储空间时,若不能确定数据类型所占字节数,可通过sizeof运算符来求得。指针应用举例-动态存储分配例: pi=(int *)malloc(sizeof(int); pf=(float *)malloc(sizeof(float);由系统来计算指定类型所占的字节数,有利于程序的移植。指针应用举例-链表单链表str

32、uct slistint data;struct slist *next;typedef struct slist SLIST;/0head指针应用举例-链表(1)建立带有头结点的单向链表步骤:读取数据生成新结点将数据存入结点的成员变量中将新结点插入到链表中。(重复操作直到输入结束)。指针应用举例-链表例:编写函数creat_slist,建立如上图所求的单向链表。结点数据域的内容从键盘输入,以-1作为输入结束标志。链表头结点的地址由函数值返回。h:头指针,存放头结点的地址r:指向链表当前的尾结点s:指向新生成的结点每当s把新开辟的结点链接到链表尾后,r便移向这一新的表尾结点。#include

33、stdio.h#include stdlib.hstruct nodeint 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,&c);while(c!=-1)s=(SLIST *)malloc(sizeof(SLIST); /*生成新结点生成新结点*/r-data =c;r-next =s;r=s; /*使使r指向当前表尾指向当前表尾*/scanf(%d,&c);r-next =0; /*置链表结束标志置链表结束标志*/return h;0headh-next=0指针应用举例-链表(1)顺序访问链表中各结点的数

温馨提示

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

评论

0/150

提交评论