《《c语言程序设计教学资料》第11章-指针与数组.ppt》由会员分享,可在线阅读,更多相关《《c语言程序设计教学资料》第11章-指针与数组.ppt(43页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第11章章 数组与指针数组与指针数数组与指与指针指指针和一和一维数数组指指针和二和二维数数组动态内存分配函数内存分配函数数组与指针数组与指针 n 一个变量有地址,一个数组包含若干元素,每个数一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地组元素都在内存中占用存储单元,它们都有相应的地址。址。n 指针变量既然可以指向变量,当然也可以指向数组指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。元素(把某一元素的地址放到一个指针变量中)。n 数组元素的指针就是数组元素的地址。数组元素的指针就是数组元素的地址。n可以用一个
2、指可以用一个指针变量指向一个数量指向一个数组元素元素 int a10=1,3,5,7,9,11,13,15,17,19;int *p;p=&a0;等价于等价于p=a;等价于等价于int*p=a;或或int*p=&a0;注意注意:数组名数组名a不代表整个数组,不代表整个数组,只代表数组首元素的地址。只代表数组首元素的地址。p=a;的作用是的作用是“把把a数组的首元素数组的首元素的地址赋给指针变量的地址赋给指针变量p”,而不是,而不是“把数组把数组a各元素的值赋给各元素的值赋给p”。指针与一维数组指针与一维数组在引用数组元素时指针的运算在引用数组元素时指针的运算在指在指针指向数指向数组元素元素时,
3、允允许以下运算:以下运算:加一个整数加一个整数(用用+或或+=),如,如p+1 减一个整数减一个整数(用用-或或-=),如,如p-1 自加运算,如自加运算,如p+,+p 自减运算,如自减运算,如p-,-p 两个指两个指针相减,如相减,如p1-p2(只有只有p1和和p2都指向同一数都指向同一数组中的元素中的元素时才有意才有意义)n 如果指如果指针变针变量量p已指向数已指向数组组中的一个元素,中的一个元素,则则p+1指向同一数指向同一数组组中的下一个元素,中的下一个元素,p-1指向同一数指向同一数组组中的上一个元素。中的上一个元素。例:例:float a10,*p=a;假假设设a0的地址的地址为为
4、2000,则则:p的的值为值为2000 p+1的的值为值为2004 p-1的的值为值为1996越界越界n 如果的初如果的初值为值为&a0,则则p+i和和a+i就是数就是数组组元素元素ai的的地址,或者地址,或者说说,它,它们们指向指向a数数组组序号序号为为i的元素的元素n*(p+i)或或*(a+i)是是p+i或或a+i所指向的数所指向的数组组元素,即元素,即ai。a0a1a2a3a4a5a6a7a8a9pp+1,a+1 p+i,a+i p+9,a+9*(p+i)通过指针引用数组元素通过指针引用数组元素引用一个数组元素,可以用:引用一个数组元素,可以用:()()下标法,如下标法,如ai形式;形式
5、;()()指针法,如指针法,如*(a+i)或或*(p+i);其中其中a是数组是数组名,名,p是指向数组元素的指针变量,其初值是指向数组元素的指针变量,其初值p=a。例:输出数组中的全部元素。例:输出数组中的全部元素。假设int a5,要输出各元素的值有四种方法:(1)下标法。下标法。(2)通过数组名计算数组元素地址,找出元素的值。通过数组名计算数组元素地址,找出元素的值。(3)用指针变量指向数组元素。用指针变量指向数组元素。虽然虽然p和和a的值都是数组的首地址,但是数组名的值都是数组的首地址,但是数组名a不能执行不能执行增增1或减或减1操作。因为数组名是指针常量,代表一个地址常操作。因为数组名
6、是指针常量,代表一个地址常量,其值不能改变;指针是变量,其值可以改变。量,其值不能改变;指针是变量,其值可以改变。3 3种方法的比种方法的比较:第第(1)(1)和第和第(2)(2)种方法种方法执行效率相同行效率相同编译系系统是将是将aiai转换为*(a+i)*(a+i)处理的,即先理的,即先计算元素算元素地址。地址。因此用第因此用第(1)(1)和第和第(2)(2)种方法找数种方法找数组元素元素费时较多。多。第第(3)(3)种方法比第种方法比第(1)(1)、第、第(2)(2)种方法快种方法快用指用指针变量直接指向元素,不必每次都重新量直接指向元素,不必每次都重新计算地址,像算地址,像p+p+这样
7、的自加操作是比的自加操作是比较快的快的这种有种有规律地改律地改变地址地址值(p+)(p+)能大大提高能大大提高执行效率行效率 用下用下标法比法比较直直观,能直接知道是第几个元素。,能直接知道是第几个元素。用地址法或指用地址法或指针变量的方法不直量的方法不直观,难以很快地判断出当前以很快地判断出当前处理的是哪一个元素。理的是哪一个元素。(4)指针的下标法指针的下标法数组名和指针变量作函数参数数组名和指针变量作函数参数a+i*(a+i);被调函数的形参声明为被调函数的形参声明为数组类型,用指针法访数组类型,用指针法访问数组元素问数组元素指针与二维数组指针与二维数组n 二维数组可以看作一维数组,其每
8、个数组元素又是二维数组可以看作一维数组,其每个数组元素又是一个一维数组一个一维数组a00a01a02aa0a1a10a11a12a00a01a02aa0a1a10 a11a12a0可以看做可以看做3个短整型元素组成的一维数组的数组名个短整型元素组成的一维数组的数组名a00a01a02a0a1a10a11a12n 如果将二维数组名如果将二维数组名a看成一个看成一个行地址行地址(第(第0行),则行),则a+i表示二维数组第表示二维数组第i行的地址,行的地址,ai可看成一个可看成一个列地址列地址,即第即第i行第行第0列的地址。列的地址。n 行地址行地址a加加1(a+1),表示指向下一行;列地址),表
9、示指向下一行;列地址ai加加1(ai+1),表示指向下一列),表示指向下一列二维数组的行指针与列指针二维数组的行指针与列指针i2;j3;i2;j3;注:注:mn个元素的二维数组个元素的二维数组int a34=1,3,5,7,9,11,13,15,17,19,21,23;1357911131517192123a0a1a2aa+1a+2a0a0+1 a0+2 a0+3行指针行指针列指针列指针a代表第代表第0行首地址行首地址a+1代表第代表第1行首地址行首地址a+2代表第代表第2行首地址行首地址1357911131517192123a0a1a2aa+1a+2a0a0+1 a0+2 a0+3行指针行指
10、针列指针列指针行指针每加行指针每加1,走一行,走一行a+i代表行号代表行号为i的行首地址(按行的行首地址(按行变化)化)*(a+i)代表什么?代表什么?1357911131517192123a0a1a2aa+1a+2a0a0+1 a0+2 a0+3行指针行指针列指针列指针相当于相当于aia0代表代表a00的地址的地址a0+1代表代表a01的地址的地址a0+2代表代表a02的地址的地址a0+3代表代表a03的地址的地址1357911131517192123a0a1a2aa+1a+2a0a0+1 a0+2 a0+3行指针行指针列指针列指针列指针每加列指针每加1,走一列,走一列a1代表代表谁的地址?
11、的地址?a1+1代表代表谁的地址?的地址?a1+2代表代表谁的地址?的地址?a1+3代表代表谁的地址?的地址?1357911131517192123a0a1a2aa+1a+2a0a0+1 a0+2 a0+3行指针行指针列指针列指针ai+j代表代表谁的地址?的地址?1357911131517192123a0a1a2aa+1a+2a0a0+1 a0+2 a0+3行指针行指针列指针列指针代表代表aij的地址的地址*(ai+j)代表什么?代表什么?代表元素代表元素aij*(*(a+i)+j)代表什么?代表什么?与与*(ai+j)等价等价动态数组动态数组栈堆静态存储区常量存储区代码区动态动态存储存储区区
12、只读只读存储存储区区低地址区低地址区高地址区高地址区n 非静态的局部变量是分配在内存中的动态存储区非静态的局部变量是分配在内存中的动态存储区的,这个存储区是一个称为的,这个存储区是一个称为栈栈的区域的区域n C语言还允许建立内存动态分配区域,以存放一些语言还允许建立内存动态分配区域,以存放一些临时用的数据,这些数据需要时随时开辟,不需要临时用的数据,这些数据需要时随时开辟,不需要时随时释放。这些数据是临时存放在一个特别的自时随时释放。这些数据是临时存放在一个特别的自由存储区,称为由存储区,称为堆堆区区n 对内存的动态分配是通过系统提供的库函数来实现对内存的动态分配是通过系统提供的库函数来实现的
13、,主要有的,主要有malloc,calloc,free,realloc这这4个函数。个函数。n 使用这些函数,要在程序开头将头文件使用这些函数,要在程序开头将头文件包含到源程序中。即包含到源程序中。即在用到这些函数时应当用在用到这些函数时应当用#include 指令把指令把stdlib.h头文件包含到程序头文件包含到程序文件中。文件中。函数原型函数原型为为:void*malloc(unsigned int size);作用作用:是在内存的是在内存的动态动态存存储储区中分配一个区中分配一个长长度度为为size的的连续连续空空间间(1)malloc函数函数例:例:malloc(100);开辟开辟1
14、00字字节节的的临时临时分配域分配域注意注意:指指针针的基的基类类型型为为void,即不指向任何,即不指向任何类类型的数据,型的数据,只提供一个地址只提供一个地址如果此函数未能成功地如果此函数未能成功地执执行(例如内存空行(例如内存空间间不足),不足),则则返回空指返回空指针针(NULL)例:例:int*p=NULL;p=(int*)malloc(2)若不清楚相应数据类型所占字节数,则若不清楚相应数据类型所占字节数,则 p=(int*)malloc(sizeof(int)函数原型函数原型为为:void*calloc(unsigned n,unsigned size);作用作用:是在内存的是在内
15、存的动态动态存存储储区中分配区中分配n个个长长度度为为size的的连续连续空空间间,这这个空个空间间一般比一般比较较大,足以保存一个数大,足以保存一个数组组。用用calloc函数可以函数可以为为一一维维数数组组开辟开辟动态动态存存储储空空间间,n为为数数组组元素个数,每个元素元素个数,每个元素长长度度为为size。这这就是就是动态动态数数组组。函数返回指向所分配域的起始位置的指函数返回指向所分配域的起始位置的指针针;如果分配;如果分配不成功,返回不成功,返回NULL。(2)calloc函数函数例:例:p=calloc(50,4);开辟开辟504个字个字节节的的临时临时分配域,把起始地址分配域,
16、把起始地址赋给赋给指指针变针变量量p 函数原型函数原型为为:void*free(void*p);作用作用:是是释释放指放指针变针变量所指向的量所指向的动态动态空空间间,使,使这这部分空部分空间间能重新被其他能重新被其他变变量使用。量使用。p应应是最近一次是最近一次调调用用calloc或或malloc函数函数时时得到的函数返回得到的函数返回值值。(3)free函数函数函数原型函数原型为为:void*realloc(void*p,unsigned int size);如果已如果已经经通通过过malloc函数或函数或calloc函数函数获获得了得了动态动态空空间间,想改想改变变其大小,可以用其大小,可以用recalloc函数重新分配。函数重新分配。用用realloc函数将函数将p所指向的所指向的动态动态空空间间的大小改的大小改变为变为size。p的的值值不不变变。如果重分配不成功,返回。如果重分配不成功,返回NULL。(4)realloc函数函数例:例:realloc(p,50);将将p所指向的已分配的所指向的已分配的动态动态空空间间改改为为50字字节节