计算机软件及应用C语言程序设计教程第7章-指课件_第1页
计算机软件及应用C语言程序设计教程第7章-指课件_第2页
计算机软件及应用C语言程序设计教程第7章-指课件_第3页
计算机软件及应用C语言程序设计教程第7章-指课件_第4页
计算机软件及应用C语言程序设计教程第7章-指课件_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

C语言程序设计第7章指针

本章需要掌握的知识点指针的概念指针的运算指针作为函数的参数时的运作方式指针跟数组的关系动态内存申请和释放内容安排

7.1指针的基本概念和运算

7.2指针与函数

7.3指针与一维数组(包含内存的动态分配)*7.4二级指针*7.5指针数组*7.6指针与二维数组*7.7命令行参数7.1指针的基本概念和运算地址和指针概念.ppt指针的概念指针是什么?地址是什么?如何定义和使用指针?为什么需要指针?程序中:inti;

floatk;

内存中每个字节有一个编号-----地址…...…...2000200120022005内存02003ik

函数调用时为其分配内存单元变量是对程序中数据存储空间的抽象地址和指针的概念…...…...2000200420062005整型变量i10变量i_pointer200120022003指针与指针变量指针:代表内存的某个地址,指向某个变量单元。指针变量:专门存放内存地址的变量叫指针变量2000指针指针变量

变量的内容

变量的地址指针变量变量变量地址(指针)变量值指向地址存入指针变量为什么需要指针方便数组和字符串的处理在调用函数时可以得到多个返回结果。动态链表建立的需要接口控制的需要指针变量的定义和使用指针变量定义的形式:

类型名*指针变量名;取变量的地址的形式:

&变量名引用变量的值方式:直接用变量名为直接引用;通过指针变量加上*号为间接引用;E1010.C1001000ap1000…...…...2000200420062005整型变量i10变量i_pointer2001200220032000指针变量200010i_pointer*i_pointer&i_pointerii_pointer&i&(*i_pointer)i*i_pointer*(&i)直接访问:按变量名存取变量值间接访问:通过变量地址去访问变量值例

i=3;-----直接访问指针变量…...…...2000200420062005整型变量i10变量i_pointer20012002200320003例*i_pointer=20;-----间接访问20注意事项如果有了定义int*p,说明p本身也是一个变量,也有地址。指针变量是有类型的。inti;float*p;p=&i;/*错误*/“*”号在定义指针和运算时所起的作用是不同的。

7.2指针与函数注意:动态内存分配内容放置在7.3进行讲解。在函数调用时,实参向形参传递的方式是什么?

单向赋值函数调用(COPY)ppt函数调用(指针)pptvoidswap(int

x,inty){inttemp;temp=x;x=y;y=temp;}voidmain(){inta,b;

scanf("%d,%d",&a,&b);if(a<b)swap(a,b);

printf("\n%d,%d\n",a,b);}例将数从大到小输出…...…...20002008200A2002200420065变量a变量b(main)9变量temp变量y变量x(swap)55959COPY实参到形参是赋值传递voidswap(int

x,inty){inttemp;temp=x;x=y;y=temp;}voidmain(){int

a,b;

scanf("%d,%d",&a,&b);

if(a<b)swap(a,b);

printf("\n%d,%d\n",a,b);}例将数从大到小输出…...…...20002008200A2002200420065变量a变量b(main)9运行结果:5,9voidswap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}voidmain(){inta,b;int*pointer_1,*pointer_2;

scanf("%d,%d",&a,&b);

pointer_1=&a;pointer_2=&b;

if(a<b)swap(pointer_1,pointer_2);

printf("\n%d,%d\n",a,b);}…...20002008200A200220042006200C200E2010...59整型变量a

整型变量b(main)指针pointer_1指针pointer_220002002(swap)指针p1指针p2整型p5920002002COPY5指针变量作为函数参数。特点:地址传递,共享内存,“双向”传递voidswap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}voidmain(){inta,b;int*pointer_1,*pointer_2;

scanf("%d,%d",&a,&b);

pointer_1=&a;pointer_2=&b;

if(a<b)swap(pointer_1,pointer_2);

printf("\n%d,%d\n",a,b);}…...20002008200A200220042006200C200E2010...59整型变量a整型变量b(main)指针pointer_1指针pointer_22000200259地址传递运行结果:9,5注意事项无论形参的类型是什么,在函数调用时,实参都是单向的将值赋给形参。为什么scanf函数中的参数是地址的列表而不是变量的列表?

scanf(“%d%d”,&a,&b);如果想在被调函数中改变调用函数中变量的值,如何做?*返回指针值的函数、指向函数的指针(自学)7.3指针与一维数组及指针的运算一个变量有地址,那么每个数组元素是否有地址?属于同一个数组的元素在内存中是放置在一起的,占用一片连续的内存,那么整个数组的地址应该如何表示比较合适?既然数组元素是放置在一起的,我们是否可以通过指针的移动来访问数组中不同的元素?如果指针可以移动,那么应该怎样移动?如果指针p指向数组a的第一个元素,那么如何引用数组第一个元素的值?如何引用数组第二个元素的值?数组的名字代表数组的首地址,该地址值不能发生改变,即数组名是一个常量指针。数组与指针ppt(一维)指针变量的赋值运算p=&a;(将变量a地址p)p=array;(将数组array首地址p)p=&array[i];(将数组元素地址p)p1=p2;(指针变量p2值p1)指针的运算指针的算术运算:指针可以加减一个整数,意义?p1与p2指向同一数组,p1-p2代表两指针间元素个数p1+p2无意义例p指向int型数组,且p=&a[0];

则p+1指向a[1]例inta[10];

int*p=&a[2];p++;*p=1;例inta[10];

int*p1=&a[2];int*p2=&a[5];

则:p2-p1?a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]a数组pp+1,a+1p+i,a+ip+9,a+91指针变量的关系运算若p1和p2指向同一数组,则p1<p2表示p1指的元素在前p1>p2表示p1指的元素在后p1==p2表示p1与p2指向同一元素若p1与p2不指向同一数组,比较无意义p==NULL或p!=NULL数组元素表示方法a[0]a[1]a[2]a[3]a[9]...aa+9a+1a+2地址元素下标法a[0]a[1]a[2]a[9]a[0]a[1]a[2]a[3]a[9]...pp+9p+1p+2地址元素指针法*p*(p+1)*(p+2)*(p+9)[]变址运算符a[i]

*(a+i)a[i]p[i]*(p+i)*(a+i)*a*(a+1)*(a+2)*(a+9)p[0]p[1]p[2]p[9]数组元素的引用方法#include"stdio.h"voidmain(){inta[5],*pa,i;for(i=0;i<5;i++) a[i]=i+1;pa=a;for(i=0;i<5;i++)

printf("*(pa+%d):%d\n",i,*(pa+i));for(i=0;i<5;i++)

printf("*(a+%d):%d\n",i,*(a+i));for(i=0;i<5;i++)

printf("pa[%d]:%d\n",i,pa[i]);for(i=0;i<5;i++)

printf("a[%d]:%d\n",i,a[i]);}例inta[]={1,2,3,4,5,6,7,8,9,10},*p=a,i=2;

数组元素地址的正确表示:

(A)&(a+1)(B)a++(C)&p(D)&p[i]数组名是地址常量p++,p--()a++,a--()a+1,*(a+2)()#include"stdio.h"voidmain(){inti,*p,a[7];p=a;for(i=0;i<7;i++)

scanf("%d",p++);

printf("\n");for(i=0;i<7;i++,p++)

printf("%d",*p);}例注意指针的当前值p=a;//指针归位pp58762730123456appppppPointerLocation.c形参中数组类型的说明自动会转变为指针的说明数组名作函数参数,是地址传递用数组名作函数参数例将数组a中的n个整数按相反顺序存放ij

379110675420123456789ijijijji11760594723voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i; t=x[i];x[i]=x[j];x[j]=t;}}voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};inv(a,10);

printf("Thereverted

array:\n");for(i=0;i<10;i++)

printf("%d,",a[i]);

printf("\n");}m=4实参与形参均用数组arrayinv.cppvoidinv(int*x,intn){intt,*p,*i,*j,m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--){t=*i;*i=*j;*j=t;}}voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};inv(a,10);

printf("Thereverted

array:\n");for(i=0;i<10;i++)

printf("%d,",a[i]);

printf("\n");}实参用数组,形参用指针变量37911067542a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]xp=x+ma数组60711594723ijijijjiji例将数组a中的n个整数按相反顺序存放voidinv(int*x,intn){intt,*i,*j,*p,m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--){t=*i;*i=*j;*j=t;}}voidmain(){inti,a[10],*p=a;for(i=0;i<10;i++,p++)

scanf("%d",p);

p=a;

inv(p,10);

printf("Thereverted

array:\n");for(p=a;p<a+10;p++)

printf(“%d,",*p);}实参与形参均用指针变量例将数组a中的n个整数按相反顺序存放voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i; t=x[i];x[i]=x[j];x[j]=t;}}voidmain(){inti,a[10],*p=a;for(i=0;i<10;i++,p++)

scanf("%d",p);

p=a;

inv(p,10);

printf("Thereverted

array:\n");

for(p=a;p<a+10;p++)

printf(“%d,",*p);}实参用指针变量,形参用数组例将数组a中的n个整数按相反顺序存放指针与字符串字符串是如何放置在字符数组中的?数组与指针(字符串).ppt例voidmain(){charstring[]="IloveChina!";

printf("%s\n",string);printf("%s\n",string+7);}IloveChistring[0]string[1]string[2]string[3]string[4]string[5]string[6]string[7]string[8]string[9]stringstring[10]string[11]string[12]string[13]n!a\0用字符数组存放一个字符串程序的运行结果是:IloveChina!China!例voidmain(){char*string=“IloveChina!”;

printf(“%s\n”,string);

string+=7;

while(*string){putchar(string[0]);string++;}}IloveChistringn!a\0字符指针初始化:把字符串首地址赋给stringchar*string;string=“IloveChina!”;string*string!=0用字符指针指向一个字符串字符串拷贝函数假如有以下定义

charsource[]=“Hello”;chardestination[100];如何将数组source中的内容复制到destination数组中?

destination=source这样是否正确?voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}voidmain(){charsource[]=“Hello”,destiantion[20] copy_string(source,destiantion);

printf(“sis%s\n”,source);

printf(“dis%s\n”,destiantion);}例:自定义一个字符串复制函数copy_string.c动态内存申请数据对象的动态申请.ppt需求求班级学生的平均成绩。班级人数在程序运行时才能确定。算法分析用户输入班级的人数,设为n输入n位学生的成绩求n位学生的总成绩和平均成绩输出平均成绩带来的问题学生人数在程序运行时才能确定,也就是说放置学生成绩的变量个数在编程时是不确定的。如果使用数组放置,但数组定义中要求元素的个数必须确定,无法满足要求。数据对象动态创建与释放的语句申请内存空间函数:malloc函数

P184

void*malloc(unsignedsize);对malloc函数的调用格式是:(指针所指对象的数据类型*)malloc(sizeof(指针所指对象的数据类型*个数))malloc函数的功能是从内存中申请一块指定字节大小的连续空间,返回该存储空间(存储块)的首地址作为函数的结果。如果申请空间失败,则说明没有足够的空间可供分配,返回空指针NULL。例1:int*pi;pi=(int*)malloc(sizeof(int));例2:int*pj;pj=(int*)malloc(sizeof(int)*10);作用:申请一个动态的整形存储单元作用:申请十个动态的整形存储单元释放内存空间函数:

free函数

P185void*free(void*p);对free函数的调用格式是:

free(指针变量名);free函数的功能是释放以指针变量名所指的位置开始的存储块,以分配时的存储块为基准。free函数与malloc函数必须配对使用,使用malloc申请的空间必须用free释放。voidmain(){ floattotal,average,*pS; intn;

printf("Pleaseinputthenumberofstudents:");

scanf("%d",&n);

pS=(float*)malloc(n*sizeof(float)); for(i=0;i<n;i++) { printf("Pleaseinputthenum%d:",i+1);

scanf("%f",pS); pS++; }…}MallocExample.c

例3:动态内存申请与释放注意事项在函数中定义的形参intppp[]相当于

int*p

温馨提示

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

评论

0/150

提交评论