您好,欢迎访问三七文档
项目6项目中指针的应用技能目标:•能正确定以指向不同类型数据的指针变量,能正确使用指针访问数据•能正确运用指针变量的运算•能用指针变量作为函数的参数知识目标:理解指针的概念,理解指针变量的定义理解指针变量作函数参数与变量作函数参数的区别理解指针在数组中的移动方法6.1任务13-1使用指针查找学生最高成绩:#includestdio.hfloatsmax(float*mathscore,intn){intj;floatmax;max=mathscore[0];for(j=1;jn;j++){if(mathscore[j]max)max=mathscore[j];}returnmax;}6.1任务13-1使用指针查找学生最高成绩:voidmain(){inti;floatscore[5];for(i=0;i5;i++)scanf(%f,,score+i);printf(%f,smax(score,5));}运行结果:6.1任务13-2使用指针查找学生最低成绩:#includestdio.hfloatsmin(float*mathscore,intn){intj;floatmin;min=mathscore[0];for(j=1;jn;j++){if(mathscore[j]min)min=mathscore[j];}returnmin;}6.1任务13-2使用指针查找学生最低成绩:voidmain(){inti;floatscore[5];for(i=0;i5;i++)scanf(%f,,score+i);printf(%f,smin(score,5));}运行结果:6.2任务14:使用指针查找成绩不合格的学生#includestdio.hvoidfun(float*score,intn,floatpassscore){inti;for(i=0;in;i++,score++){if(*scorepassscore)printf(第%d个学生成绩不合格,其成绩为:%.2f\n,i,*score);}}voidmain(){inti;floatx;floatscore[5];for(i=0;i5;i++)scanf(%f,,score+i);fun(score,5,60.0);}运行结果:#includestdio.hvoidasc(float*score,intn){inti,j,k;floattemp;for(i=0;in-1;i++)for(j=0;jn-i-1;j++)if(score[j]score[j+1]){temp=score[j];score[j]=score[j+1];score[j+1]=temp;}任务:使用指针对学生成绩排序for(k=0;kn;k++)printf(%f,,score[k]);printf(\n);}voidmain(){inti;floatscore[5];for(i=0;i5;i++)scanf(%f,,score+i);asc(score,5);}运行结果:6.4必备知识与理论指针是数据类型。利用指针变量可以表示各种数据结构;能很方便地使用数组和字符串;并能像汇编语言一样处理内存地址,从而编出精练而高效的程序。6.4.1地址与指针1.程序实体的内存地址一个程序一经编译,在其执行过程中,就会为变量、数组以及函数分配存储空间。这些变量、数组、函数都称为程序实体,也具有某一种数据类型。这些被分配了内存空间的程序实体,都具有自己的内存地址。例:变量在内存中的存储和地址分配#includestdio.hintmain(void){inti1,i2;floatf1,f2;doubled1,d2;printf(数据大小:int,%d;float,%d;double,%d\n,sizeof(i1),sizeof(f1),sizeof(d1));/*输出类型宽度*/printf(i1的地址为:%ld,i2的地址为:%ld\n,&i1,&i2);printf(f1的地址为%ld,f2的地址为%ld\n,&f1,&f2);printf(d1的地址为%ld,d2的地址为%ld\n,&d1,&d2);return0;}运行结果:从栈底建立,后建的变量地址小指针的概念一个指针所指变量的类型,称为该指针的基类型。内存地址就称为指针。存储器中一个字节称为一个存储单元。存储单元的编号叫做地址。对于一个内存单元来说,单元的地址即为指针,其中存放的数据为该单元的内容。C语言中允许用一个变量来存放指针,这个变量称指针变量。一个指针变量的值就是某内存单元的地址。指针变量是指取值为地址的变量。定义指针的目的是为了通过指针去访问内存单元。指针的概念一个指针变量可以存放一个数组或一个函数的首地址。数组或函数在内存中连续存放。即指针指向数据结构的首地址。指针变量是指取值为地址的变量。指针指向数据结构的首地址。在一个指针变量中可以存放一个数组或一个函数的首地址。指针的概念6.4.2指针变量的定义、初始化与赋值变量可以用来存放数值(如整数、实数等),也可以用来存放地址(另一个变量的地址),这种专门用于存储地址的变量就称为指针变量。1.指针变量的定义在定义指针变量时,需要用指针声明符*。定义指针变量时,需要声明该变量的类型。定义一个指针的语法格式为:基类型标识符*指针变量名;例:int*pi1,*pi2;double*pd1,*pd2;说明:(1)“基类型”,就是指针要指向的数据的类型。(2)定义指针变量时,在指针变量名前加符号“*”。“*”称为指针声明符,用于说明它后面的名字是一个指针变量名。例如语句:inti1,i2,*pi1,*pi2;定义了两个数据变量i1和i2,还定义了两个指向int类型的指针pi1和pi2。可以用变量的地址对指针变量进行初始化,注意:该变量的类型必须和指针变量的基类型相同。也可以用一个指针变量的值给另一个指针变量赋值,但它们应该具有相同的基类型。例如:inti1,i2,i3;int*pi1=&i1,*pi2=&i2;pi1=&i3;pi2=pi1;2.指针变量的初始化和赋值注意,不要将一个变量的值赋给指向它的指针变量。例如:pi1=i1;或pi2=i1;都是错误的。1.引用指针变量在C语言中使用指针访问它所指向的内存空间的方法是在指针变量名前加一个“*”号。例如inti,*pi;pi=&i;*pi=8;6.4.3指针变量的引用“*”是“指针运算符”*pi表示指针变量pi所指向的存储空间,即变量i。*pi相当于变量i。例6-2变量的直接访问与间接访问#includestdio.hintmain(void){inta,b;int*pointer_1,*pointer_2;a=100;b=10;pointer_1=&a;/*把变量a的地址赋给pointer_1*/pointer_2=&b;/*把变量b的地址赋给pointer_2*/printf(变量的直接访问:a=%d,b=%d\n,a,b);printf(变量的间接访问:a=%d,b=%d\n,*pointer_1,*pointer_2);return0;}运行结果:运行结果一样#includestdio.hintmain(void){inti1=10,i2=20,*p,*p1,*p2;p1=&i1;p2=&i2;printf(i1=%d,*p1=%d;i2=%d,*p2=%d\n,i1,*p1,i2,*p2);p=p1;p1=p2;p2=p;/**/printf(i1=%d,*p1=%d;i2=%d,*p2=%d\n,i1,*p1,i2,*p2);}例6-3:使两个变量交换指向指针指向的单元变了,所指向的内容也变了运行结果:交换指针所指向的对象i1&i2i2&i1p1p2交换前指针指向交换后指针指向#includestdio.hintmain(void){int*p1,*p2,i1=1,i2=2,i;p1=&i1;p2=&i2;printf(i1=%d,*p1=%d;i2=%d,*p2=%d\n,i1,*p1,i2,*p2);i=*p1;*p1=*p2;*p2=I;printf(i1=%d,*p1=%d;i2=%d,*p2=%d\n,i1,*p1,i2,*p2);}交换两个指针变量所指向的变量值交换变量i1和i2的值运行结果:上题p=p1;p1=p2;p2=p;i1&i2i2&i1p1p2ii=*p1*p1=*p2①②③*p2=i功能:交换变量i1和i2的值3.关于运算符“*”和“&”的讨论例:inti=100;int*pi=&i;等价于int*pi;pi=&i;pi=&i;指针pi的值就是变量i的地址。*pi=i;*pi就是pi所指向的变量,即i。例:*pi++,相当于*(pi++)(*pi)++,为先取pi所指单元的值,然后将其加1。指针是一种数据类型。指针不能进行下列运算:两个指针相加、相乘、相除、移位;不同基类型指针之间的相减、赋值。指针可以进行的运算:移动;同类型指针的比较和相减运算;6.4.4指针的运算#includestdio.hintmain(void){inti,*pi;doubled,*pd;pi=&i;pd=&d;printf(pi=%ld,pi+1=%ld\n,pi,pi+1);printf(pd=%ld,pd+1=%ld\n,pd,pd+1);return0;}运行结果:CPU不一样,结果不一样地址加4地址加86.4.7数组元素的指针引用1.一维数组元素的指针引用数组元素在内存是连续存储的,并通过下标引用数元素。下标增1,数据改变一个数据单元位置。C语言的数组元素有两种引用方式:下标引用方式和指针引用方式。#includestdio.hintmain(void){inta[5]={1,3,5,7,9},i,*p;printf(下标法:);for(i=0;i5;i++)printf(%d,,a[i]);printf(\n数组名法:);for(i=0;i5;i++)printf(%d,,*(a+i));printf(\n指针变量法:);for(p=a;pa+5;p++)printf(%d,,*p);printf(\n);return0;}指针的概念运行结果:结果一样,指针法速度最快在计算机的系统中有四个内存区域:1)栈:在栈里面储存一些我们定义的局部变量以及形参(形式参数);2)字符常量区:主要是储存一些字符常量,比如:char*p_str=“cgat”;其中“cgat”就储存在字符常量区里面;3)全局区:在全局区里储存一些全局变量和静态变量;4)堆:堆主要是通过动态分配的储存空间,也就是我们接下需要讲的动态分配内存空间。6.4.9内存的动态分配与动态数组的建立什么时候我们需要动态分配内存空间呢?举一个例子吧。int*p;定义一个指向int类型的指针p;p是用来储存一个地址的值,我们之所以要为p这个变量分配空间是让它有一个明确的指向。打个比方吧!你现在做好了一个指向方向的路标,但是你并没有让这个路标指向一个确切的方位,这样我们就不能够通过它来明确到底哪里是东,哪里是西,何为北,何为南。这样我们就要通过动态分配内存的方式来规定它的方向!int*p;p=malloc(n*sizeof(类型名称));我们通过malloc()函数为一个指针变量p分配地址,这样我们从键盘上键入的值就存储在p里面了,接下来我们就可以对这个p进行具体的操作了,比如scanf(“%s”,p)等等。当我们对p结束操作的时候还要释放p的内存空间。为什么要释放内存空间呢?动态分配的变量储存在堆里面,但是这个堆的空间并不是无限大的,当我们编一个小的程序的时候并不能够发现什么,但是对于大的程序,如果我们不及时释放堆的空间的时候会产生内存泄露。所谓内存泄露是堆的空间被我们动态分配用完了,这样当我们再去使用动态分配堆的空间的时候就没有足够的空间让我们使用了,这样就需要占有原来的空间,也就会把其他
本文标题:指针的定义和应用
链接地址:https://www.777doc.com/doc-5017417 .html