版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第6章 指针6.4 指针与数组及字符串 6.5 指针数组和多级指针 6.4 指针与数组及字符串6.4.1 指针与数组 C语言中,指针和数组之间的关系十分密切,它们都可以处理内存中连续存放的一系列数据,数组与指针在访问内存时采用统一的地址计算方法。数组内部的处理就是依赖于指针运算来实现的。 数组是相同数据类型的数据集合、数组用其下标变化实现对内存中的数组元素进行处理。 例如,程序中说明了一个数组:int a10; 编译系统在一定的内存区域为该数组分配了存放int型(字节)数据的个连续存储空间,它们分别是a0, a1,,a9。用ai表示从数组存储首地址开始的第i+1个元素变量。1/1若程序中同时说
2、明了一个int型指针: int *pa;并且通过指针赋值运算: pa=a; 或pa=&a0;指针pa就指向了数组a的首地址。这时指针的目标变量*pa就是a0。 指针pa+1的目标变量*(pa+1)就是a1, *(pa+2)就是a2 *(pa+i)就是ai,如下图所示:4/5例6.5 指针与数组的关系#include void main() int a10, *pa, i; for (i = 0; i 10; i+) ai = i + 1; / 将指针指向数组的第一个元素 pa = a; /建立指向数组的指针pa for (i = 0; 10; i+) printf(*(pa+%d):%dn,
3、i, *(pa + i) ); / 用指针的形式逐个输出数组元素内容运行结果:* (pa+0):1* (pa+1):2* (pa+2):3* (pa+3):4* (pa+4):5* (pa+5):6* (pa+6):7* (pa+7):8* (pa+8):9* (pa+9):10程序中第一个for循环是把1-10赋予数组元素a0-a9。然后通过pa=a; 使指针指向数组。再用第二个for循环,通过指针运算输出显示数组中的数据。3/8(1)上述表现形式ai和*(pa+i)实质上是两个运算表达式,它们遵循统一的地址计算规则实现相同的功能。 (2)当指针pa指向数组a时,就可以用ai、*(pa+i)
4、、*(a+i)和pai等四种形式来访问数组的元素,都是完成同样功能的表达式。(3)在程序中它们可以互换使用,恰当地使用指针与数组表现形式的互换性,可以使程序表现形式更简洁。 3/11元素ai的地址表示:a+i故*(a+i)等价于ai运算符称为变址运算符数组名是基址,下标是偏移量即:数组名偏移*(基址+偏移)二者等价兑换例6.6 指针和数组表现形式的互换性#include void main( ) int i,*pa; int a=2,4,6,8,10; pa=a; /建立指针 /指针采用数组的形式使用 for (i=0 ; i5 ; i+) printf (”a%d:%d ”, i , ai
5、); printf (”n”);/数组采用指针的形式使用 for(i=0 ; i5 ; i+) printf (”*(pa+%d):%d”, i , *(pa+i) ); printf (”n”);a i*(pa+i)运行结果:a0:2 a1:4 a2:6 a3:8 a4:10*(pa+0):2 *(pa+1):4 *(pa+2):6 *(pa+3):8 *(pa+4):10 指针加下标和数组名加下标在访问地址空间中的数据时,其表现形式具有相同的意义,这是因为指针和数组名都是地址量。 a i*(pa+i)pai*(a+i)3/14特别注意: 指针和数组在访问地址中的数据时,其表现形式具有相同的
6、意义,但是,指针和数组名在本质上是不同的:指针是地址变量,而数组名是地址常量, 区别在于能否作为左值。对于指针pa和数组名a。 pa = a; pa+, pa- ,&pa/正确 a+,a- ,&a /错误。 ai可以转换成 *(pa + i)的前提是指针pa指向了数组a ,即pa指向数组a的第一个元素,否则不能转换 。但ai可以用*(a+i)来等价。2/16除了用ai,*(a+i),pai,*(pa+i)来表示数组元素外,还有一种表示方法:*pa+因此,一旦建立了指向数组的指针pa,共有5种表示方法6.4.2 字符指针与字符串 C语言使用char型数组保存字符串。可以用数组名+下标来处理字符数
7、组中的字符串,也可以用字符型的指针来处理。 在字符串的处理中,使用字符指针比使用字符型数组加下标有更大的便利性。(1) 在字符指针初始化时,可以直接用字符串常量作为初始值。例如, char *pa=”ABC”;(2) 在程序中也可以直接把一个字符串常量赋予一个指针。例如, char *p; p=”c program”; 这里2例都是用指针指向常量数据区的字符串,故通过指针能进行的操作只有间接读操作,不能写操作!到底给指针变量pa和p赋了什么值?是字符串文字量吗?不是! pa的值是存放A的内存字节单元地址,即“ABC”存储区域的入口地址到底给指针变量pa和p赋了什么值?是字符串文字量吗? 6/2
8、2例6.8 向字符指针赋予字符串程序。#include void main( ) char *s=”good”; char *p; while(*s!=0) printf(”%c”,*s+); printf(”n”); p=”morning”; while(*p!=0) printf(”%c”,*p+); printf(”n”);scanf( )和printf( )函数使用字符指针输入或输出字符串。这时的转换说明符使用%s,输入项和输出项都使用指针名。指针名的含义分别为保存键盘输入字符串的内存单元入口地址和输出到屏幕的字符串其存储单元的入口地址。设p是一个有确定指向的字符指针,则输入字符串时使
9、用形式是: scanf(”%s”,p);/gets(p);输出字符串时使用形式是: printf(”%s”,p);/puts(p);存放字符串”good”的几种形式:1、存放在常量内存区2、定义一个字符数组存放字符串3、用malloc()/new在堆数据区 分配内存空间保存字符串scanf不能用指向常量区的指针 5/27puts(s);printf(“%s”,s);puts(p);printf(“%s”,p);6.5 指针数组和多级指针先回顾一下二维数组a的降维概念了解降维过程中存在多个不同类型的指针:a和ai 1/28二维数组的逻辑结构图如下:a00a01a02a03a10a11a12a13
10、a20a21a22a23a0a1a2a+0a+2a+1ai*(a+i)aij*(*(a+i)+j)不是*(*(a+i+j) 3/316.5 指针数组和多级指针6.5.1 指针数组 一系列有次序的指针变量集合成指针数组,其每一个元素都是一个指针变量,相当于多个指向相同数据类型的指针变量。指针数组的说明形式如下:存储类型 目标数据类型 *指针数组名元素个数; 和普通数组一样,编译系统在处理指针数组定义时,按照指定的存储类型为它在内存的相应数据区中分配一定的存储空间,这时指针数组名就表示该指针数组的存储首地址。 例如,有下列的自动指针数组定义: auto int *p3; 2/33 在程序中,指针数
11、组可以用来处理多维数组。例如,程序中有一个二维数组,其说明如下: int a23;采用降低维数的方法,这个二维数组可以分解为a0和a12个一维数组,它们各有3个元素。若同时存在一个指针数组: int *pa2;它由两个指针pa0和pa1组成,并对其进行赋值:pa0=a0;或pa0=&a00; pa1=a1;或pa1=&a10; 2/35则两个指针分别指向了两个一维数组的入口元素,这时通过两个指针就可以对二维数组中的数据进行处理。 如下图: 3/38例6.9 用指针数组处理二维数组的数据#include void main( ) int data23, *pdata2; int i,j; /二维
12、数组赋值 for (i=0 ; i2 ; i+) for (j=0 ; j3 ; j+) dataij= (i+1) *(j+1); /将指针数组的各个元素指向降维后的 /一维数组 pdata0=data0; pdata1=data1; /采用指针数组输出数组内容 for ( i=0 ; i2 ; i+) for ( j=0 ; j3 ; j+ , pdatai+) printf (”data%d%d:%2dn”,i,j, *pdata i); 运行结果:data00:1data01:2data02:3data10:2data11:4data12:6在程序中, dataij pdataij *
13、(datai+j) *(pdatai+j) *(*(data+i)+j) *(*(pdata+i)+j)*pdatai+是意义相同的表示方法。指针数组在定义的同时可以进行初始化。应该记住,不能用auto型变量的地址去初始化内部的static型指针。因为初始化的时机! 7/45例6.11 字符指针数组的初始化#include void main( ) /指针数组初始化 static char * monthname = illegal month,January,February, March,April, June,July,August,September October,November,
14、December; int month; /无限循环,由循环体中的break语句退出循环 while (1) printf (Enter month No.: ); scanf (%d,&month); /输入月份 if (month12) /月份错误,退出循环 printf (Month No.%d-%sn,month, monthname 0); break; /打印月份对应的英文名称 printf (Month No.%d-%sn,month, monthname month); while循环为无限循环,当输入的整数不在1-12的范围内时,用break语句退出循环。注意字符串常量的存放
15、位置及不可修改的处理特性 3/48例6.12 多个字符串按字母递增方式排序#include #include void main() / 指针数组初始化 char *pstr = test, capital, index, large, small ; int a, b, n = 5; / 采用直接选择法进行排序 for (a = 0; a n - 1; a+) for (b = 0; b 0 ) char * temp; temp = pstrb; pstrb = pstrb+1; pstrb+1 = temp; for (a = 0; a 5; a+) / 输出排序后的字符串 printf
16、(%sn, pstra);运行结果:capitalindexlargesmalltest在程序中,调用了标准函数字符串比较函数:int strcmp (char *s1,char *s2 )其中s1,s2是要比较的两个字符串的指针。当字符串s1大于、等于或小于s2时,函数返回值分别是正数,零和负数。If语句中能否用strcpy实现字符串的拷贝?参考下图思考改成交换法 5/53 2/55 6.5.2 多级指针 在C语言中,指针数组也可以用另外一个指针处理。例如,有一字符指针数组str3,它说明如下:char *name4= ”TurboC”,”BorlandC+”,”Access”,”; 它的三
17、个元素name0, name1和name2都是指针,分别指向一个字符串。如果同时存在另一个指针变量pp,并且把指针数组的首址赋予指针pp:pp=name或pp=&name0 pp就指向了指针数组name 。这时pp的目标变量*pp就是name0, *(pp+1)就是name1,*(pp+2)就是name2。pp就是指向指针型数据的指针变量。 5/60 二级指针的说明形式如下:存储类型 目标数据类型 *指针名; 例如,一个二级指针pp的说明如下: auto char *pp; 二级指针说明中,存储类型是二级指针本身的存储类型,而数据类型是最终目标变量,即处理数据的数据类型。所以,上述定义中指明了
18、 *pp是char型。 2/62例6.13 二级指针处理多个字符串#include #define Null 0void main() char *pp; /指针数组的赋初值 char *name = Turbo C+, BorlandC+, Access, ; pp = name; / 将二级指针指向指针数组的首地址 while ( *pp != Null ) / 是空字符串,终止循环 printf(%sn, *pp+); / 采用二级指针输出字符串运行结果:Turbo C+BorlandC+Accessstrlen(*pp)!=0!(strcmp(*pp,“”)=0)用空串做循环终结不是最
19、佳方法,见演示案例 8/70例6.14多级指针应用#include char *str = ”enter”,”lamp”,”point”,”first”; /一级指针数组声明及初始化char *p = str+3,str+2, str+1,str; /二级指针数组声明及初始化char *pp=p; /三级指针声明及初始化void main( ) printf(”%s”,*+pp); printf(”%s”,*-*+pp+3); printf(”%s”,*pp-2+3); printf(”%s”,pp-11+1);运行结果:pointerstamp多级指针功能较强,但使用起来比较复杂,缺乏易读性,容易出错!
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2026年济南历城区八年级第二学期数学期中考试试题以及答案
- 新汽车基础制造 5
- 肉羊羔羊育成期饲养管理规程
- 运动后营养补充搭配指南
- 拖拉机年检维修保养制度
- 沉睡会员客户唤醒营销服务方案
- 排污许可自行监测执行记录规范
- 葡萄避雨栽培生产管理指引
- 甜菜根腐线虫防治技术措施
- 客户退单退费处理管理规定细则
- 初中八年级英语下册 Unit 7 Natural Disasters 写作提升课:灾害事件报道与个人经历叙述教案
- TSG 31-2025工业管道安全技术规程
- 2026年离婚登记申请书
- 中型水库管理岗位责任制度
- 2026校招:中国农业发展真题及答案
- 2026年人形机器人(Optimus类)项目商业计划书
- 2026中国新闻社招聘应届高校毕业生11人考试参考试题及答案解析
- 火花探测检查制度规范
- DB41∕T 2877-2025 道路深层病害高聚物注浆处治技术规范
- 化工职业卫生培训课件
- kuka库卡机器人培训
评论
0/150
提交评论