语言详解指针和数组.pptx
《语言详解指针和数组.pptx》由会员分享,可在线阅读,更多相关《语言详解指针和数组.pptx(65页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、预习检查链表单元有哪几个部分组成如何申请链表单元,及释放链表单元实现单链表插入的基本语法简述一下快速排序基本理论要点第1页/共65页课程目标本章概述指针与数组什么时候相同C语言为什么把数组参数当作指针C语言的多维数组,及如何创建动态数组。本章目标 掌握指针什么时候和数组相同,以为容易混淆的原因掌握多维数组的内存布局。使用指针向函数传递多维数组参数使用指针返回多维数组使用指针创建和使用动态数组重点 指针和数组混淆的原因指针传递多维数组参数难点 指针和数组混淆的原因创建和使用动态数组 第2页/共65页本章结构指针与数组不相同再论指针和数组指针数组和数组指针指针与数组相同函数指针和指针函数怎样使用数
2、组指针运算第3页/共65页1 再论指针和数组指针与数组的不相同 指针与数组的相同 怎样使用指针 指针运算 函数指针和指针函数指针数组和数组指针第4页/共65页1.1 指针与数组的不相同 数组和指针是如何访问的 数组访问指针数据 使声明与定义相匹配 数组和指针的其他区别 第5页/共65页1.1.1数组和指针是如何访问的 申明区别extern int*x;声明x是个int型的指针 extern int y y是个int型数组,长度尚未确定 地址和内容的区别X=YX=Y在这个上下文环境里,在这个上下文环境里,符号符号x x的含义是的含义是x x所代所代表的地址。表的地址。在这个上下文环境里,在这个上
3、下文环境里,符号符号Y Y的含义是的含义是Y Y所代表所代表的地址的内容。的地址的内容。这被称为左值。这被称为左值。这被称为右值。这被称为右值。左值在编译时可知,左值在编译时可知,左值表示存储结果的左值表示存储结果的地方。地方。右值直到运行时才知。右值直到运行时才知。如无特别说明,如无特别说明,右值右值表示表示“Y Y的内容的内容”。第6页/共65页1.1.1数组和指针是如何访问的 数组下标引用特点地址在编译时可知 直接进行操作 例:数组:char a9“abedefgh”;.取值:c=ai+1+1+2+2+3+3+4+4+i+i9980998099809980编译器符号表具有一个地址9980
4、运行步骤:1.取i的值,将它与9980相加2.取地址(9980i)的内容。图A第7页/共65页1.1.2 数组访问指针数据 指针访问特点必须首先在运行时取得它的当前值 间接进行操作 例:指针:char*p取值:c=*p 5081编译器符号表有一个符号p,它的地址为4624运行步骤:1.取地址4624的内容,就是50812.取地址5081的内容。50814642图B第8页/共65页1.1.2 数组访问指针数据 数组访问指针特点对内存进行直接的引用转化为间接引用例:数组:char a9“abedefgh”;.取值:c=ai5 0 8 1编译器符号表有一个符号p,它的地址为4624运行步骤:1.取地
5、址4624的内容,即5081。2.取得i的值,并将它与5081相加。3.取地址508l+i的内容。50814642+1+2+3+i5081+i图C第9页/共65页1.1.2 数组访问指针数据 指针访问特点char*p=“abcdefgh”;p3 dchar a=”abcdefgh”;a3 d访问特点取得符号表中P的地址,提取存储于此处的指针。把下标所表示的偏移量与指针的值相加,产生一个地址。访问上面这个地址,取得字符。第10页/共65页1.1.3 数组和指针的其他区别 指指 针针 数数 组组保存数据的地址保存数据的地址保存数据保存数据间接访问数据,首先取得指针的内容,间接访问数据,首先取得指针
6、的内容,把它作为地址,然后从这个地址把它作为地址,然后从这个地址提取数据。提取数据。如果指针有一个下标如果指针有一个下标I,就把指针的,就把指针的内容加上内容加上I作为地址,从中提取数作为地址,从中提取数据据直接访问数据,直接访问数据,aI只是简单地以只是简单地以a*1为地址取得数为地址取得数据据通常用于动态数据结构通常用于动态数据结构通常用于存储固定数目且数据类型相同的元素。通常用于存储固定数目且数据类型相同的元素。相关的函数为相关的函数为malloc(),free()。隐式分配和删除隐式分配和删除通常指向匿名数据通常指向匿名数据自身即为数据名自身即为数据名第11页/共65页1.2 指针与数
7、组的相同 什么时候指针与数组相同 混淆的原因数组和指针规则为什么C语言把数组形参当作指针 数组与指针归纳总结 第12页/共65页1.2.1 什么时候指针与数组相同 数组运用特性数组声明外部数组(external array)的声明 数组的定义 函数参数的声明 运用特性作为函数参数的数组名可以通过编译器转换为指针使用数组时,数组可以写成指针 ,可以互换 第13页/共65页1.2.1 什么时候指针与数组相同 数组与指针编译器处理时是不同的 一个数组就是一个地址 一个指针就是一个地址的地址 在运行时的表示形式也是不一样的 可能产生不同的代码第14页/共65页1.2.2 数组和指针混淆的原因分析:ch
8、army_array10char*my_ptr;.j=strlen(my_array);J=strlen(my_ptr);printf(”ss”,my_ptr,my_array);第15页/共65页1.2.2 数组和指针混淆的原因 数组和指针是相同的规则表达式中的数组名(与声明不同)被编译器当作一个指向该数组第一个元素的指针1。下标总是与指针的偏移量相同在函数参数的声明中,数组名被编译器当作指向该数组第一个元素的指针第16页/共65页1.2.3 数组和指针规则“表达式中的数组名”就是指针 C语言把数组下标作为指针的偏移量“作为函数参数的数组名”等同于指针 第17页/共65页1.2.3.1“表达
9、式中的数组名”就是指针 数组下标的引用一个指向数组的起始地址的指针加上偏移量”下标值的步长调整到数组元素的大小 整型数的长度是4个字节,那么ai+1和ai在内存中的距离就是4(而不是1)例:访问ai:int a10;int*p;Int i=2;p=a;pi;p=a;*(p+i);p=a+i;*p;访问数组第i个元素的三张方式第18页/共65页1.2.3.1“表达式中的数组名”就是指针 数组的引用不能用指向该数组第一个元素的指针规则数组作为sizeof()的操作数一显然此时需要的是整个数组的大小,而不是指针所指向的第一个元素的大小。使用&操作符取数组的地址。数组是一个字符串(或宽字符串)常量初始
10、值。第19页/共65页1.2.3.2 C语言把数组下标作为指针的偏移量 数组访问模式分析数组访问for(i=0;i10;i+)Ai=0;把左值把左值(a)装入装入Rl(可以提到循环外可以提到循环外)把左值把左值(i)装入装入R2(可以提到循环外可以提到循环外)把把R2装入装入R3如果需要,对如果需要,对R3的步长进行调整把的步长进行调整把R1+R3的结果装入的结果装入R4中中把把0存储到存储到R4第20页/共65页1.2.3.2 C语言把数组下标作为指针的偏移量 数组访问模式分析指针备选方案1p=a;for(i=0;i10;i+)pi=0;把左值把左值(p)装入装入R0(可以提到循环外可以提到
11、循环外)把把R0装入装入Rl(可以提到循环外可以提到循环外)把左值把左值(i)装入装入R2(可以提到循环外可以提到循环外)把把R2装入装入R3如果需要,对如果需要,对R3的步长进行调整的步长进行调整把把R1+R3的结果装入的结果装入R4中中把把0存储到存储到R4。第21页/共65页1.2.3.2 C语言把数组下标作为指针的偏移量 数组访问模式分析指针备选方案1p=a;for(i=0;i10;i+)*p+=0;把左值把左值(p)装入装入R0(可以提到循环外可以提到循环外)把把R0装入装入Rl(可以提到循环外可以提到循环外)把左值把左值(i)装入装入R2(可以提到循环外可以提到循环外)把把R2装入
12、装入R3如果需要,对如果需要,对R3的步长进行调整的步长进行调整把把R1+R3的结果装入的结果装入R4中中把把0存储到存储到R4。第22页/共65页1.2.3.2 C语言把数组下标作为指针的偏移量 数组访问模式分析指针备选方案p=a;for(i=0;i10;i+)*(p+i)=0;把把P所指对象的大小装入所指对象的大小装入R5(可以提到循环外可以提到循环外)把左值把左值(p)装入装入Rl(可以提到循环外可以提到循环外)把把R0装入装入Rl把把0存储至存储至UR1把把R5+R1的结果装入的结果装入Rl把把Rl存储到存储到R0第23页/共65页1.2.4 为什么C语言把数组形参当作指针 数组运用特
13、性数组声明外部数组(external array)的声明 数组的定义 函数参数的声明 第24页/共65页1.2.4 为什么C语言把数组形参当作指针 出于效率的考虑?传值调用与传址调用 C语言形参特性非数组形式的数据实参均以传值形式 拷贝整个数据拷贝整个数组,在时间上还是在内存空间上的开销都非常大 所有的数组在作为参数传递时都转换为指向数组起始地址的指针,而其他的参数均采用传值调用 函数的返回值绝不能是一个函数数组,而只能是指向数组或函数的指针 第25页/共65页1.2.4 为什么C语言把数组形参当作指针 例:展示了对一个下标形式的数组形参进行访问所需要的几个步骤。Func(charp);c=p
14、iFunc(char*p);c=pi编译器符号表显示p可以取址,从堆栈指针sp偏移14个位置运行时步骤1:从sp偏移14个位置找到函数的活动记录,取出实参。步骤2:取i的值,并与5081相加。步骤3:取出地址(508i)的内容。第26页/共65页1.2.4 为什么C语言把数组形参当作指针 数组,指针实参的一般用法 调用时的实参调用时的实参 类类 型型 通常目的通常目的func(&my_int);func(my_int_ptr);func(my_int_array);func(&my_int_arrayi)一个整型数的地址一个整型数的地址指向整型数的指针指向整型数的指针整型数组整型数组一个整型数
15、组某个元素的地址一个整型数组某个元素的地址一个一个int参数的传址调用参数的传址调用传递一个指针传递一个指针传递一个数组传递一个数组传递数组的一部分传递数组的一部分第27页/共65页1.2.5 数组与指针归纳总结 用ai这样的形式对数组进行访问总是被编译器“改写”或解释为像*(a+1)这样的指针访问。指针始终就是指针。它绝不可以改写成数组。在特定的上下文中,也就是它作为函数的参数(也只有这种情况),一个数组的声明可以看作是一个指针。作为函数参数的数组(就是在一个函数调用中)始终会被编译器修改成为指向数组第一个元素的指针。当把一个数组定义为函数的参数时,可以选择把它定义为数组,也可以定义指针。不
16、管选择哪种方法,在函数内部事实上获得的都是一个指针。定义和声明必须匹配 第28页/共65页1.3 怎样使用数组 多维数组向函数传递一个多维数组从函数返回一个数组 第29页/共65页1.3.1 多维数组多维数组特性多维数组内存布局如何分解多维数组 如何对数组进行初始化 第30页/共65页1.3.1.1 多维数组特性 定义和引用多维数组惟一的方法就是使用数组的数组 注意:i jk 与I,j,k多维数组看作是一种向量 多维数组的定义声明一个1020的多维字符数组 char carrot1020;或者声明一种看上去更像“数组的数组”形式:typedef char vegetable20;vegetab
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 详解 指针 数组
限制150内