C语言程序设计_第五章指针

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

云淡风清gsqls.blog.163.com第五章指针第1页共13页第五章指针重点:1、C语言中指针的概念2、指针变量的相关操作3、指针与数组的关系4、内存空间的动态分配第1节C语言中指针一、指针与指针变量一台计算机的内存单元非常多,为了相互区分,就给它们采取编号的方法,按十进来说,从0开始编号,即0,1,2……,这种对每个内存单元的唯一的编号叫做内存单元的地址。计算机对内存的访问一般采取“按地址访问”的方式。变量(指前面所讲的普通变量)的实质对应的是内存单元,对变量的操作实质是对相应内存单元中所存放的数据的操作:给变量赋一个值,实质是将一个值存入与此变量对应的内存单元;读取一个变量的值,实质是从对应的内存单元中取出存放的数据。有时,我们要用到内存单元的地址,这种情况下,可利用C语言中的“指针”数据类型来实现。指针就是变量的地址,实质是内存单元的地址。可以用变量来存放指针,称为指针变量,但跟普通变量不同的是,普通变量存放数据,指针变量存放的是变量的地址,即内存单元的地址。1、指针变量的定义数据类型符*变量名;如:int*a,*b;float*fp;2、指针变量的赋值1)初始化赋值数据类型*指针名=初始地址值;例:intx=20;//定义了一个普通的整型变量int*p=&x;//定义了一个指向整型变量的指针变量,并让p指向变量x所对应的内存单元,即p中存入x所对应的内存单元的地址。如下图:例:inti;int*p=&i;20变量x10000批针p云淡风清gsqls.blog.163.com第五章指针第2页共13页int*q=p;2)赋值语句赋值inta;int*p;p=&a;3、与指针相关的运算符&:取地址运算符,获得变量的地址*:访问指针所指变量内容的运算符上例中,要获得内存单元10000中的内容有两种办法:①直接访问:按变量名来存取变量值。上例中可通过x来实现;②间接访问:通过存放变量地址的指针变量去访问。上例中可通过*p访问。注意:p代表地址而*p代表内容。例:输入两个数,并使其从大到小顺序输出,用指针实现。#includestdio.hvoidmain(){inta,b,*p1,*p2,*p;printf(\n请输入两个整数:);scanf(%d%d,&a,&b);p1=&a;p2=&b;if(*p1*p2b){p=p1;p1=p2;p2=p;}printf(a=%d,b=%d\n,a,b);printf(max=%d,min=%d\n,*p1,*p2);}说明:1、指针变量必须先定义,后赋值,最后才能使用!没有赋值的指针变量是没有任何意义的,也绝对是不允许使用的。如下例:#includestdio.hvoidmain(){int*p1,*p2;云淡风清gsqls.blog.163.com第五章指针第3页共13页printf(\n请输入两个整数:);scanf(%d%d,p1,p2);printf(max=%d,min=%d\n,*p1,*p2);}例中的指针变量p1和p2没有赋值,使用时就会出错。2、指针变量只能指向定义时所规定类型的变量。如果给指针赋值时,=号右边的指针类型与左边的指针类型不同,则需要进行类型强制转换。例:inta;int*pi;char*pc;pi=&a;//pi指向apc=(char*)pi;//pc也指向了a,即pi和pc的值都是a的地址3、普通变量随着类型的不同,在内存中所分配的内存单元可能也会发生变化。指针变量也是变量,在内存中也要占用一定的内存单元,但所有类型的指针变量都占用同样大小的内存单元,其具体大小取决于所使用的编译环境,如在VC6.0下为4个字节,在TC2.0下为2个字节。二、指针和地址运算1、指针变量的加、减运算指针可以参与加、减运算,但其加、减的含义不同于一般数值的加减运算。如下例:#includestdio.hvoidmain(){int*pi;char*pc;pi=(int*)1000;printf(\npi=%d,pi);pc=(char*)1000;printf(\npc=%d,pc);pi++;//pi的值将是1004(假设int型占4B)printf(\npi=%d,pi);pi-=2;//pi的值将是996printf(\npi=%d,pi);pc++;//pc的值将是1001云淡风清gsqls.blog.163.com第五章指针第4页共13页printf(\npc=%d,pc);pc-=2;//pc的值将是999printf(\npc=%d,pc);}如果指针p是这样定义的:ptype*p;并且p当前的值是ADDR,那么:p±n的值=ADDR±n*sizeof(ptype)即指针加上或减去一个整数相当于将指针以定义时所用的数据类型占用内存的字节数为单位向后或向前移动n个单位。两个指针相加没有任何意义,但两个指针相减则有一定的意义,可表示两指针之间所相差的内存单元数或元素的个数,在后面的学习中就会体会到。2、指针变量的关系运算若p1和p2指向同一类型的变量,则p1p2表示p1所指的单元在p2之前p1p2表示p1所指的单元在p2之后p1==p2表示p1与p2指向共同的单元若p1与p2指向的是同一数组中的元素(变量),则上述比较有意义,否则比较没有实际意义第2节指针与数组的关系一、数组的指针与指向数组的指针变量1、数组的指针:其实就是数组在内存中的起始地址。而数组在内存中的起始地址就是数组变量名,也就是数组第一个元素(下标为0)在内存中的地址。如下图:云淡风清gsqls.blog.163.com第五章指针第5页共13页p+1指向数组的下一个元素,而不是简单地使指针变量p的值+1。其实际变化为p+1*size(size为一个元素占用的字节数)。2、指向数组的指针变量:如果将数组的起始地址赋给某个指针变量,那么该指针变量就是指向数组的指针变量。如上图:下面是对数组元素赋值的几种方法,它们从功能上是等价的:方法一:charstr[10];intk;for(k=0;k10;k++)str[k]='A'+k;//也可写成*(str+k)='A'+k方法二:charstr[10],*p;intk;p=str;for(k=0;k10;k++)p[k]='A'+k;//也可写成*(p+k)='A'+k方法三:charstr[10],*p;intk;p=str;for(k=0;k10;k++)*p++='A'+k;//相当于*p='A'+k;p++;注意:数组名是地址常量,切不可对其赋值,也不可做++或--运算。例如:inta[10];如果在程序中出现a++或a--则是错误的。下面一个例子用来说明数组元素的各种不同引用方法:#includestdio.hvoidmain(){inta[2],*pa,i;for(i=0;i2;i++)a[i]=i+1;pa=a;for(i=0;i2;i++)printf(*(pa+%d):%d\n,i,*(pa+i));for(i=0;i2;i++)printf(*(a+%d):%d\n,i,*(a+i));for(i=0;i2;i++)printf(pa[%d]:%d\n,i,pa[i]);for(i=0;i2;i++)printf(a[%d]:%d\n,i,a[i]);}云淡风清gsqls.blog.163.com第五章指针第6页共13页例:设有如下定义:inta[]={1,2,3,4,5,6,7,8,9,10},*p=a,i;下列对数组元素地址的正确表示是:(A)&(a+1)(B)a++(C)&p(D)&p[i]二、二维数组与指针的关系二维数组可看作是特殊的一维数组:其每个元素本身就是一个一维数组。C语言中的二维数组在内存中是按“行序优先”的方式排列。看下例:#includestdlib.h#includestdio.hvoidmain(){inta[2][3]={{1,2,3},{4,5,6}};inti,j,*p;p=&a[0][0];for(i=0;i2;i++){for(j=0;j3;j++)printf(%8d%8d,p,*p++);printf(\n);}system(pause);}运行结果如下:第3节指针与字符串用C语言表示字符串时有如下两种形式:一、用字符数组实现例:云淡风清gsqls.blog.163.com第五章指针第7页共13页#includestdio.hvoidmain(){charstring[]=IloveChina!;printf(%s\n,string);printf(%s\n,string+7);}二、用字符指针实现例:#includestdio.hvoidmain(){char*string=IloveChina!;printf(%s\n,string);string+=7;puts(string);}#includestdio.hvoidmain(){char*string=IloveChina!;printf(%s\n,string);string+=7;while(*string){putchar(string[0]);//也可以写成putchar(*string);string++;}}三、字符指针变量与字符数组char*cp;与charstr[20];1、str由若干元素组成,每个元素放一个字符;而cp中只存放字符串首地址。云淡风清gsqls.blog.163.com第五章指针第8页共13页charstr[20];str=“IloveChina!”;()char*cp;cp=“IloveChina!”;()2、str是地址常量;cp是地址变量cp接受键入字符串时,必须先开辟存储空间例charstr[10];scanf(“%s”,str);()而char*cp;scanf(“%s”,cp);()改为:char*cp,str[10];cp=str;scanf(“%s”,cp);()3、当字符指针指向字符串时,除了可以被赋值之外,与包含字符串的字符数组没有什么区别。charstr[10],*pstr;pstr=12345;//pstr指向12345strcpy(str,pstr);//将pstr所指向的字符串复制到数组str中pstr=str;printf(TheLengthofstris:%d\n,strlen(pstr));//输出字符串的长度5四、字符串与数组关系字符串用一维字符数组存放字符数组具有一维数组的所有特点数组名是指向数组首地址的地址常量数组元素的引用方法可用指针法和下标法数组名作函数参数是地址传递区别存储格式:字符串结束标志赋值方式与初始化输入输出方式:%s%ccharstr[]={“Hello!”};()charstr[]=“Hello!”;()charstr[]={‘H’,‘e’,‘l’,‘l’,‘o’,‘!’};()char*cp=“Hello”;()云淡风清gsqls.blog.163.com第五章指针第9页共13页inta[]={1,2,3,4,5};()int*p={1,2,3,4,5};()charstr[10],*cp;inta[10],*p;str=“Hello”;()cp=“Hello!”;()a={1,2,3,4,5};()p={1,2,3,4,5};()例:输入一组人员姓名,先按原序输出,再排好序后输出。#includestdio.h#includestdlib.h#includestring.h#defineRENSHU50#defineN10voidmain(){charname[RENSHU+1][N];inti,j,renshu;printf(\n请输入人数(1-%d):,RENSHU);scanf(%d,&renshu);if((renshu1)||(renshuRENSHU))printf(\n输入的人数超出范围!);else{printf(\n请

1 / 13
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功