C语言程序设计指针C语言学.doc_第1页
C语言程序设计指针C语言学.doc_第2页
C语言程序设计指针C语言学.doc_第3页
C语言程序设计指针C语言学.doc_第4页
C语言程序设计指针C语言学.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

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

文档简介

C语言程序设计 指针C语言学习重点:1、语言中指针的概念2、指针变量的相关操作3、指针与数组的关系4、内存空间的动态分配 第节C语言中指针 一、指针与指针变量一台计算机的内存单元非常多,为了相互区分,就给它们采取编号的方法,按十进来说,从0开始编号,即0,1,2,这种对每个内存单元的唯一的编号叫做内存单元的地址。计算机对内存的访问一般采取“按地址访问”的方式。变量(指前面所讲的普通变量)的实质对应的是内存单元,对变量的操作实质是对相应内存单元中所存放的数据的操作:给变量赋一个值,实质是将一个值存入与此变量对应的内存单元;读取一个变量的值,实质是从对应的内存单元中取出存放的数据。有时,我们要用到内存单元的地址,这种情况下,可利用C语言中的“指针”数据类型来实现。指针就是变量的地址,实质是内存单元的地址。可以用变量来存放指针,称为指针变量,但跟普通变量不同的是,普通变量存放数据,指针变量存放的是变量的地址,即内存单元的地址。1、指针变量的定义数据类型符*变量名;如:int *a,*b;float *fp;2、指针变量的赋值1)初始化赋值数据类型 *指针名=初始地址值;例:int x=20;/定义了一个普通的整型变量int *p=&x; /定义了一个指向整型变量的指针变量,并让p指向变量x所对应的内存单元,即p中存入x所对应的内存单元的地址。如下图:例:int i;int *p = &i;int *q = p;2)赋值语句赋值int a;int *p;p = &a;3、与指针相关的运算符&:取地址运算符,获得变量的地址*:访问指针所指变量内容的运算符上例中,要获得内存单元10000中的内容有两种办法:直接访问:按变量名来存取变量值。上例中可通过x来实现;间接访问:通过存放变量地址的指针变量去访问。上例中可通过*p访问。注意:p代表地址而*p代表内容。例:输入两个数,并使其从大到小顺序输出,用指针实现。#include void main( ) int a,b,*p1,*p2,*p; printf(n请输入两个整数:); scanf (%d%d,&a,&b); p1=&a; p2=&b; if(*p1*p2) p=p1;p1=p2;p2=p; printf(a=%d,b=%dn,a,b); printf(max=%d,min=%dn,*p1,*p2);说明:1、指针变量必须先定义,后赋值,最后才能使用!没有赋值的指针变量是没有任何意义的,也绝对是不允许使用的。如下例:#include stdio.hvoid main( ) int *p1,*p2; printf(n请输入两个整数:); scanf (%d%d,p1,p2); printf(max=%d,min=%dn,*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、指针变量的加、减运算指针可以参与加、减运算,但其加、减的含义不同于一般数值的加减运算。如下例:#include stdio.hvoid main() 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的值将是996 printf(npi=%d,pi); pc+;/pc的值将是1001 printf(npc=%d,pc); pc-=2;/pc的值将是999 printf(npc=%d,pc);如果指针p是这样定义的:ptype*p;并且p当前的值是ADDR,那么:pn 的值=ADDRn*sizeof(ptype)即指针加上或减去一个整数相当于将指针以定义时所用的数据类型占用内存的字节数为单位向后或向前移动n个单位。两个指针相加没有任何意义,但两个指针相减则有一定的意义,可表示两指针之间所相差的内存单元数或元素的个数,在后面的学习中就会体会到。2、指针变量的关系运算若p1和p2指向同一类型的变量,则p1p2 表示p1所指的单元在p2之后p1=p2 表示p1与p2指向共同的单元若p1与p2指向的是同一数组中的元素(变量),则上述比较有意义,否则比较没有实际意义 第2节指针与数组的关系 一、数组的指针与指向数组的指针变量1、数组的指针:其实就是数组在内存中的起始地址。而数组在内存中的起始地址就是数组变量名,也就是数组第一个元素(下标为0)在内存中的地址。如下图:p + 1指向数组的下一个元素,而不是简单地使指针变量p的值+1。其实际变化为p+1*size(size为一个元素占用的字节数)。2、指向数组的指针变量:如果将数组的起始地址赋给某个指针变量,那么该指针变量就是指向数组的指针变量。如上图:下面是对数组元素赋值的几种方法,它们从功能上是等价的:方法一:char str10;int k;for(k=0;k10;k+) strk=A+k; /也可写成*(str+k)=A+k方法二:char str10,*p;int k;p=str;for(k=0;k10;k+) pk=A+k; /也可写成*(p+k)=A+k方法三:char str10,*p;int k;p=str;for(k=0;k10;k+) *p+=A+k; /相当于 *p=A+k; p+;注意:数组名是地址常量,切不可对其赋值,也不可做+或-运算。例如:int a10;如果在程序中出现a+或a-则是错误的。下面一个例子用来说明数组元素的各种不同引用方法:#include void main( ) int a2,*pa,i; for(i=0;i2;i+) ai=i+1; pa=a; for(i=0;i2;i+) printf(*(pa+%d):%dn,i,*(pa+i); for(i=0;i2;i+) printf(*(a+%d):%dn,i,*(a+i); for(i=0;i2;i+) printf(pa%d:%dn,i,pai); for(i=0;i2;i+) printf(a%d:%dn,i,ai);例:设有如下定义:int a=1,2,3,4,5,6,7,8,9,10,*p=a,i;下列对数组元素地址的正确表示是:(A)&(a+1) (B)a+ (C)&p (D)&pi二、二维数组与指针的关系二维数组可看作是特殊的一维数组:其每个元素本身就是一个一维数组。C语言中的二维数组在内存中是按“行序优先”的方式排列。看下例:#include #include void main() int a23=1,2,3,4,5,6; int i,j,*p; p=&a00; for(i=0;i2;i+) for(j=0;j3;j+) printf(%8d%8d,p,*p+); printf(n); system(pause);运行结果如下:第3节指针与字符串 用C语言表示字符串时有如下两种形式:一、用字符数组实现例:#include void main ( ) char string = I love China!; printf (%sn, string); printf (%sn, string + 7);二、用字符指针实现例:#include void main ( ) char *string = I love China!; printf(%sn, string); string+=7; puts(string);#include void main ( ) char *string = I love China!; printf(%sn, string); string+=7; while(*string) putchar(string0);/也可以写成putchar(*string); string+; 三、字符指针变量与字符数组char *cp;与char str20;1、str由若干元素组成,每个元素放一个字符;而cp中只存放字符串首地址。char str20; str=“I love China!”; ()char *cp; cp=“I love China!”; (?)2、str是地址常量;cp是地址变量cp接受键入字符串时,必须先开辟存储空间例 char str10;scanf(“%s”,str); (?)而 char *cp;scanf(“%s”,cp); ()改为:char *cp,str10;cp=str;scanf(“%s”,cp); (?)3、当字符指针指向字符串时,除了可以被赋值之外,与包含字符串的字符数组没有什么区别。char str10, *pstr;pstr=12345; /pstr指向12345strcpy(str,pstr); /将pstr所指向的字符串复制到数组str中pstr=str;printf(The Length of str is: %dn, strlen(pstr); /输出字符串的长度5四、字符串与数组关系字符串用一维字符数组存放字符数组具有一维数组的所有特点数组名是指向数组首地址的地址常量数组元素的引用方法可用指针法和下标法数组名作函数参数是地址传递区别存储格式:字符串结束标志赋值方式与初始化输入输出方式:%s %cchar str=“Hello!”; (?)char str=“Hello!”; (?)char str=H,e,l,l,o,!; (?)char *cp=“Hello”; (?)int a=1,2,3,4,5; (?)int *p=1,2,3,4,5; () char str10,*cp;int a10, *p;str=“Hello”;()cp=“Hello!”;(?)a=1,2,3,4,5;()p=1,2,3,4,5;()例:输入一组人员姓名,先按原序输出,再排好序后输出。#include stdio.h#include stdlib.h#include string.h #define RENSHU 50#define N 10void main() char nameRENSHU+1N; int i,j,renshu; printf(n请输入人数(1%d):,RENSHU); scanf(%d,&renshu); if(renshuRENSHU) printf(n输入的人数超出范围!); else printf(n请输入%d个人的姓名,姓名最长五个汉字:n,renshu); for(i=1;i=renshu;i+) scanf(%s,&namei); printf(n排序前:n); for(i=1;i=renshu;i+) printf(%8s,namei); for(i=1;i=i+1;j-) if(strcmp(namej,namej-1)0) strcpy(name0,namej); strcpy(namej,namej-1); strcpy(namej-1,name0); printf(n排序后:n); for(i=1;i=renshu;i+) printf(%8s,namei); printf(n); system(pause); 第3节指针与动态内存分配 一、静态内存分配当程序中定义变量或数组以后,系统就会给变量或数组按照其数据类型及大小来分配相应的内存单元,在程序运行过程中分配给它们的内存空间大小是不固定不变的,这种内存分配方式称为静态内存分配。二、动态内存分配动态内存分配是指在程序运行过程中,根据程序的实际需要来分配一块大小合适的连续的内存单元,即“按需分配”。动态分配的内存大小可以由用户自行按需要确定。例:编写程序利用C语言的随机函数rand产生一组(最多10000个)小于1000的随机数,先按产生的原顺序输出,再降序排序后并输出,要求在程序运行时先确定要产生的数字的个数,然后按要求根本内存空间。此例中要产生数值的个数不定,可以由用户在程序运行时从键盘输入,然后将产生的数值放入一个数组即可。为了建立跟要求的空间大小相符的数组,可以用空间的动态分配解决此问题。动态分配的实现:1、内存空间的分配:C语言中动态内存分配其实就是使用一个标准的库函数malloc,格式如下:void *malloc(unsigned int size );说明:1)size这个参数的含义是分配的内存的大小(以字节为单位)。2)返回值:失败,则返回值是NULL(空指针);成功,则返回值是一个指向空类型(void)的指针(即所分配内存块的首地址)。3)malloc前面必须要加上一个指针类型转换符,如前面的(int *)。因为malloc的返回值是空类型的指针,一般应与右边的指针变量类型一致。malloc所带的一个参数是指需分配的内存单元字节数,尽管可以直接用数字来表示,但一般写成如下形式: 分配数量*sizeof(内存单元类型符)sizeof()是系统的一个标准函数,用于返回所指定的数据类型所占用的内存字节数。malloc可能返回NULL,表示分配内存失败,因此一定要检查分配的内存指针是否为空,如果是空指针,则不能引用这个指针,否则会造成系统崩溃。所以在动态内存分配的语句的后面一般紧跟一条if语句以判断分配是否成功。4)动态分配的内存需要有一个指针变量记

温馨提示

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

评论

0/150

提交评论